[Intel-gfx] [PATCH v2 33/40] drm: Optimise power-of-two alignments in drm_mm_scan_add_block()

2016-12-15 Thread Chris Wilson
For power-of-two alignments, we can avoid the 64bit divide and do a
simple bitwise add instead.

v2: s/alignment_mask/remainder_mask/

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c | 9 -
 include/drm/drm_mm.h | 1 +
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index ff1e62c066e8..ffa439b2bd2c 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -742,8 +742,12 @@ void drm_mm_scan_init_with_range(struct drm_mm_scan *scan,
 
scan->mm = mm;
 
+   if (alignment <= 1)
+   alignment = 0;
+
scan->color = color;
scan->alignment = alignment;
+   scan->remainder_mask = is_power_of_2(alignment) ? alignment - 1 : 0;
scan->size = size;
scan->flags = flags;
 
@@ -811,7 +815,10 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
if (scan->alignment) {
u64 rem;
 
-   div64_u64_rem(adj_start, scan->alignment, );
+   if (likely(scan->remainder_mask))
+   rem = adj_start & scan->remainder_mask;
+   else
+   div64_u64_rem(adj_start, scan->alignment, );
if (rem) {
adj_start -= rem;
if (scan->flags != DRM_MM_CREATE_TOP)
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index 639d00eb8f28..6ee87e1455bf 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -110,6 +110,7 @@ struct drm_mm_scan {
 
u64 size;
u64 alignment;
+   u64 remainder_mask;
 
u64 range_start;
u64 range_end;
-- 
2.11.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 40/40] drm: kselftest for drm_mm and bottom-up allocation

2016-12-15 Thread Chris Wilson
Check that if we request bottom-up allocation from drm_mm_insert_node()
we receive the next available hole from the bottom.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/selftests/drm_mm_selftests.h |   1 +
 drivers/gpu/drm/selftests/test-drm_mm.c  | 102 +++
 2 files changed, 103 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index 6a4575fdc1c0..37bbdac52896 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -17,6 +17,7 @@ selftest(align32, igt_align32)
 selftest(align64, igt_align64)
 selftest(evict, igt_evict)
 selftest(evict_range, igt_evict_range)
+selftest(bottomup, igt_bottomup)
 selftest(topdown, igt_topdown)
 selftest(color, igt_color)
 selftest(color_evict, igt_color_evict)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index 97468b8b33a0..081b5a1c565f 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -1653,6 +1653,108 @@ static int igt_topdown(void *ignored)
return ret;
 }
 
+static int igt_bottomup(void *ignored)
+{
+   RND_STATE(prng, random_seed);
+   const unsigned int count = 8192;
+   unsigned int size;
+   unsigned long *bitmap;
+   struct drm_mm mm;
+   struct drm_mm_node *nodes, *node, *next;
+   unsigned int *order, n, m, o = 0;
+   int ret, err;
+
+   /* Like igt_topdown, but instead of searching for the last hole,
+* we search for the first.
+*/
+
+   ret = -ENOMEM;
+   nodes = vzalloc(count * sizeof(*nodes));
+   if (!nodes)
+   goto err;
+
+   bitmap = kzalloc(count / BITS_PER_LONG * sizeof(unsigned long),
+GFP_TEMPORARY);
+   if (!bitmap)
+   goto err_nodes;
+
+   order = drm_random_order(count, );
+   if (!order)
+   goto err_bitmap;
+
+   ret = -EINVAL;
+   for (size = 1; size <= 64; size <<= 1) {
+   drm_mm_init(, 0, size*count);
+   for (n = 0; n < count; n++) {
+   err = drm_mm_insert_node_generic(, [n],
+size, 0, n,
+DRM_MM_INSERT_LOW);
+   if (err || !assert_node([n], , size, 0, n)) {
+   pr_err("bottomup insert failed, size %u step 
%d\n", size, n);
+   ret = err ?: -EINVAL;
+   goto out;
+   }
+
+   if (!assert_one_hole(, size*(n + 1), size*count))
+   goto out;
+   }
+
+   if (!assert_continuous(, size))
+   goto out;
+
+   drm_random_reorder(order, count, );
+   drm_for_each_prime(n, min(count, max_prime)) {
+   for (m = 0; m < n; m++) {
+   node = [order[(o + m) % count]];
+   drm_mm_remove_node(node);
+   __set_bit(node_index(node), bitmap);
+   }
+
+   for (m = 0; m < n; m++) {
+   unsigned int first;
+
+   node = [order[(o + m) % count]];
+   err = drm_mm_insert_node_generic(, node, 
size, 0, 0,
+
DRM_MM_INSERT_LOW);
+   if (err || !assert_node(node, , size, 0, 0)) 
{
+   pr_err("insert failed, step %d/%d\n", 
m, n);
+   ret = err ?: -EINVAL;
+   goto out;
+   }
+
+   first = find_first_bit(bitmap, count);
+   if (node_index(node) != first) {
+   pr_err("node %d/%d not inserted into 
bottom hole, expected %d, found %d\n",
+  m, n, first, node_index(node));
+   goto out;
+   }
+   __clear_bit(first, bitmap);
+   }
+
+   DRM_MM_BUG_ON(find_first_bit(bitmap, count) != count);
+
+   o += n;
+   }
+
+   drm_mm_for_each_node_safe(node, next, )
+   drm_mm_remove_node(node);
+   DRM_MM_BUG_ON(!drm_mm_clean());
+   }
+
+   ret = 0;
+out:
+   drm_mm_for_each_node_safe(node, next, )
+   drm_mm_remove_node(node);
+   drm_mm_takedown();
+   kfree(order);
+err_bitmap:
+   

[Intel-gfx] [PATCH v2 22/40] drm/i915: Build DRM range manager selftests for CI

2016-12-15 Thread Chris Wilson
Build the struct drm_mm selftests so that we can trivially run them
within our CI.

"Enable debug, become developer." - Joonas Lahtinen

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/Kconfig.debug | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/Kconfig.debug 
b/drivers/gpu/drm/i915/Kconfig.debug
index 597648c7a645..598551dbf62c 100644
--- a/drivers/gpu/drm/i915/Kconfig.debug
+++ b/drivers/gpu/drm/i915/Kconfig.debug
@@ -24,6 +24,7 @@ config DRM_I915_DEBUG
 select X86_MSR # used by igt/pm_rpm
 select DRM_VGEM # used by igt/prime_vgem (dmabuf interop checks)
 select DRM_DEBUG_MM if DRM=y
+   select DRM_DEBUG_MM_SELFTEST
select DRM_I915_SW_FENCE_DEBUG_OBJECTS
 default n
 help
-- 
2.11.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 35/40] drm: Apply tight eviction scanning to color_adjust

2016-12-15 Thread Chris Wilson
Using mm->color_adjust makes the eviction scanner much tricker since we
don't know the actual neighbours of the target hole until after it is
created (after scanning is complete). To work out whether we need to
evict the neighbours because they impact upon the hole, we have to then
check the hole afterwards - requiring an extra step in the user of the
eviction scanner when they apply color_adjust.

v2: Massage kerneldoc.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/drm_mm.c| 76 ++---
 drivers/gpu/drm/i915/i915_gem_evict.c   |  7 +++
 drivers/gpu/drm/selftests/test-drm_mm.c | 20 -
 include/drm/drm_mm.h|  1 +
 4 files changed, 77 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 91c89ae09b26..22db356e3ebc 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -692,19 +692,21 @@ EXPORT_SYMBOL(drm_mm_replace_node);
  * The DRM range allocator supports this use-case through the scanning
  * interfaces. First a scan operation needs to be initialized with
  * drm_mm_scan_init() or drm_mm_scan_init_with_range(). The driver adds
- * objects to the roaster (probably by walking an LRU list, but this can be
- * freely implemented) until a suitable hole is found or there's no further
- * evictable object.
+ * objects to the roster (probably by walking an LRU list, but this can be
+ * freely implemented) (using drm_mm_scan_add_block()) until a suitable hole
+ * is found or there are no further evictable objects.
  *
  * The driver must walk through all objects again in exactly the reverse
  * order to restore the allocator state. Note that while the allocator is used
  * in the scan mode no other operation is allowed.
  *
- * Finally the driver evicts all objects selected in the scan. Adding and
- * removing an object is O(1), and since freeing a node is also O(1) the 
overall
- * complexity is O(scanned_objects). So like the free stack which needs to be
- * walked before a scan operation even begins this is linear in the number of
- * objects. It doesn't seem to hurt badly.
+ * Finally the driver evicts all objects selected (drm_mm_scan_remove_block()
+ * reported true) in the scan, and any overlapping nodes after color adjustment
+ * (drm_mm_scan_evict_color()). Adding and removing an object is O(1), and
+ * since freeing a node is also O(1) the overall complexity is
+ * O(scanned_objects). So like the free stack which needs to be walked before a
+ * scan operation even begins this is linear in the number of objects. It
+ * doesn't seem to hurt too badly.
  */
 
 /**
@@ -829,23 +831,8 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
}
}
 
-   if (mm->color_adjust) {
-   /* If allocations need adjusting due to neighbouring colours,
-* we do not have enough information to decide if we need
-* to evict nodes on either side of [adj_start, adj_end].
-* What almost works is
-* hit_start = adj_start + (hole_start - col_start);
-* hit_end = adj_start + scan->size + (hole_end - col_end);
-* but because the decision is only made on the final hole,
-* we may underestimate the required adjustments for an
-* interior allocation.
-*/
-   scan->hit_start = hole_start;
-   scan->hit_end = hole_end;
-   } else {
-   scan->hit_start = adj_start;
-   scan->hit_end = adj_start + scan->size;
-   }
+   scan->hit_start = adj_start;
+   scan->hit_end = adj_start + scan->size;
 
DRM_MM_BUG_ON(scan->hit_start >= scan->hit_end);
DRM_MM_BUG_ON(scan->hit_start < hole_start);
@@ -903,6 +890,45 @@ bool drm_mm_scan_remove_block(struct drm_mm_scan *scan,
 EXPORT_SYMBOL(drm_mm_scan_remove_block);
 
 /**
+ * drm_mm_scan_color_evict - evict overlapping nodes on either side of hole
+ * @scan: drm_mm scan with target hole
+ *
+ * After completing an eviction scan and removing the selected nodes, we may
+ * need to remove a few more nodes from either side of the target hole if
+ * mm.color_adjust is being used.
+ *
+ * Returns:
+ * A node to evict, or NULL if there are no overlapping nodes.
+ */
+struct drm_mm_node *drm_mm_scan_color_evict(struct drm_mm_scan *scan)
+{
+   struct drm_mm *mm = scan->mm;
+   struct drm_mm_node *hole;
+   u64 hole_start, hole_end;
+
+   DRM_MM_BUG_ON(list_empty(>hole_stack));
+
+   if (!mm->color_adjust)
+   return NULL;
+
+   hole = list_first_entry(>hole_stack, typeof(*hole), hole_stack);
+   hole_start = __drm_mm_hole_node_start(hole);
+   hole_end = __drm_mm_hole_node_end(hole);
+
+   DRM_MM_BUG_ON(hole_start > scan->hit_start);
+   DRM_MM_BUG_ON(hole_end < scan->hit_end);
+
+   mm->color_adjust(hole, scan->color, _start, _end);
+ 

[Intel-gfx] [PATCH v2 15/40] drm: kselftest for drm_mm and alignment

2016-12-15 Thread Chris Wilson
Check that we can request alignment to any power-of-two or prime using a
plain drm_mm_node_insert(), and also handle a reasonable selection of
primes.

v2: Exercise all allocation flags

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/selftests/drm_mm_selftests.h |   3 +
 drivers/gpu/drm/selftests/test-drm_mm.c  | 110 +++
 2 files changed, 113 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index 92b2c1cb10fa..a7a3763f8b20 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -12,3 +12,6 @@ selftest(reserve, igt_reserve)
 selftest(insert, igt_insert)
 selftest(replace, igt_replace)
 selftest(insert_range, igt_insert_range)
+selftest(align, igt_align)
+selftest(align32, igt_align32)
+selftest(align64, igt_align64)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index 94cd0741c5b6..dc3aee222158 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -970,6 +970,116 @@ static int igt_insert_range(void *ignored)
return 0;
 }
 
+static int igt_align(void *ignored)
+{
+   const struct insert_mode *mode;
+   const unsigned int max_count = min(8192u, max_prime);
+   struct drm_mm mm;
+   struct drm_mm_node *nodes, *node, *next;
+   unsigned int prime;
+   int ret = -EINVAL, err;
+
+   /* For each of the possible insertion modes, we pick a few
+* arbitrary alignments and check that the inserted node
+* meets our requirements.
+*/
+
+   nodes = vzalloc(max_count * sizeof(*nodes));
+   if (!nodes)
+   goto err;
+
+   drm_mm_init(, 1, U64_MAX - 2);
+
+   for (mode = insert_modes; mode->name; mode++) {
+   unsigned int i = 0;
+
+   drm_for_each_prime(prime, max_count) {
+   u64 size = drm_next_prime_number(prime);
+
+   err = drm_mm_insert_node_generic(,
+[i],
+size, prime, i,
+mode->search_flags,
+mode->create_flags);
+   if (err || !assert_node([i], , size, prime, 
i)) {
+   pr_err("%s insert failed with alignment=%d",
+  mode->name, prime);
+   ret = err ?: -EINVAL;
+   goto out;
+   }
+
+   i++;
+   }
+
+   drm_mm_for_each_node_safe(node, next, )
+   drm_mm_remove_node(node);
+   DRM_MM_BUG_ON(!drm_mm_clean());
+   }
+
+   ret = 0;
+out:
+   drm_mm_for_each_node_safe(node, next, )
+   drm_mm_remove_node(node);
+   drm_mm_takedown();
+   vfree(nodes);
+err:
+   return ret;
+}
+
+static int igt_align_pot(int max)
+{
+   struct drm_mm mm;
+   struct drm_mm_node *node, *next;
+   int bit;
+   int ret = -EINVAL;
+
+   /* Check that we can align to the full u64 address space */
+
+   drm_mm_init(, 1, U64_MAX - 1);
+
+   for (bit = max - 1; bit; bit--) {
+   u64 align, size;
+   int err;
+
+   node = kzalloc(sizeof(*node), GFP_KERNEL);
+   if (!node) {
+   ret = -ENOMEM;
+   goto out;
+   }
+
+   align = BIT_ULL(bit);
+   size = BIT_ULL(bit-1) + 1;
+   err = drm_mm_insert_node_generic(, node, size, align, bit,
+DRM_MM_SEARCH_DEFAULT,
+DRM_MM_CREATE_DEFAULT);
+   if (err || !assert_node(node, , size, align, bit)) {
+   pr_err("insert failed with alignment=%llx [%d]",
+  align, bit);
+   ret = err ?: -EINVAL;
+   goto out;
+   }
+   }
+
+   ret = 0;
+out:
+   drm_mm_for_each_node_safe(node, next, ) {
+   drm_mm_remove_node(node);
+   kfree(node);
+   }
+   drm_mm_takedown();
+   return ret;
+}
+
+static int igt_align32(void *ignored)
+{
+   return igt_align_pot(32);
+}
+
+static int igt_align64(void *ignored)
+{
+   return igt_align_pot(64);
+}
+
 #include "drm_selftest.c"
 
 static int __init test_drm_mm_init(void)
-- 
2.11.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 37/40] drm: Apply range restriction after color adjustment when allocation

2016-12-15 Thread Chris Wilson
mm->color_adjust() compares the hole with its neighbouring nodes. They
only abutt before we restrict the hole, so we have to apply color_adjust
before we apply the range restriction.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/drm_mm.c | 16 ++--
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index da9f98690e97..062a2a82efd6 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -410,14 +410,12 @@ static void drm_mm_insert_helper_range(struct drm_mm_node 
*hole_node,
 
DRM_MM_BUG_ON(!drm_mm_hole_follows(hole_node) || node->allocated);
 
-   if (adj_start < start)
-   adj_start = start;
-   if (adj_end > end)
-   adj_end = end;
-
if (mm->color_adjust)
mm->color_adjust(hole_node, color, _start, _end);
 
+   adj_start = max(adj_start, start);
+   adj_end = min(adj_end, end);
+
if (flags & DRM_MM_CREATE_TOP)
adj_start = adj_end - size;
 
@@ -625,17 +623,15 @@ static struct drm_mm_node 
*drm_mm_search_free_in_range_generic(const struct drm_
   flags & DRM_MM_SEARCH_BELOW) {
u64 hole_size = adj_end - adj_start;
 
-   if (adj_start < start)
-   adj_start = start;
-   if (adj_end > end)
-   adj_end = end;
-
if (mm->color_adjust) {
mm->color_adjust(entry, color, _start, _end);
if (adj_end <= adj_start)
continue;
}
 
+   adj_start = max(adj_start, start);
+   adj_end = min(adj_end, end);
+
if (!check_free_hole(adj_start, adj_end, size, alignment))
continue;
 
-- 
2.11.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 13/40] drm: kselftest for drm_mm_replace_node()

2016-12-15 Thread Chris Wilson
Reuse drm_mm_insert_node() with a temporary node to exercise
drm_mm_replace_node(). We use the previous test in order to exercise the
various lists following replacement.

v2: Check that we copy across the important (user) details of the node.
The internal details (such as lists and hole tracking) we hope to detect
errors by exercise.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/selftests/drm_mm_selftests.h |  1 +
 drivers/gpu/drm/selftests/test-drm_mm.c  | 64 +---
 2 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index 727c6d7255e0..dca726baa65d 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -10,3 +10,4 @@ selftest(init, igt_init)
 selftest(debug, igt_debug)
 selftest(reserve, igt_reserve)
 selftest(insert, igt_insert)
+selftest(replace, igt_replace)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index 9621820a1cda..dca146478b06 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -526,7 +526,7 @@ static const struct insert_mode {
{}
 };
 
-static int __igt_insert(unsigned int count, u64 size)
+static int __igt_insert(unsigned int count, u64 size, bool replace)
 {
RND_STATE(prng, random_seed);
const struct insert_mode *mode;
@@ -541,7 +541,7 @@ static int __igt_insert(unsigned int count, u64 size)
DRM_MM_BUG_ON(!size);
 
ret = -ENOMEM;
-   nodes = vzalloc(count * sizeof(*nodes));
+   nodes = vmalloc(count * sizeof(*nodes));
if (!nodes)
goto err;
 
@@ -554,7 +554,10 @@ static int __igt_insert(unsigned int count, u64 size)
 
for (mode = insert_modes; mode->name; mode++) {
for (n = 0; n < count; n++) {
-   node = [n];
+   struct drm_mm_node tmp;
+
+   node = replace ?  : [n];
+   memset(node, 0, sizeof(*node));
err = drm_mm_insert_node_generic(, node, size, 0, n,
 mode->search_flags,
 mode->create_flags);
@@ -564,6 +567,28 @@ static int __igt_insert(unsigned int count, u64 size)
ret = err ?: -EINVAL;
goto out;
}
+
+   if (replace) {
+   drm_mm_replace_node(, [n]);
+   if (drm_mm_node_allocated()) {
+   pr_err("replaced old-node still 
allocated! step %d\n",
+  n);
+   goto out;
+   }
+
+   if (!assert_node([n], , size, 0, n)) {
+   pr_err("replaced node did not inherit 
parameters, size %llu step %d\n",
+  size, n);
+   goto out;
+   }
+
+   if (tmp.start != nodes[n].start) {
+   pr_err("replaced node mismatch location 
expected [%llx + %llx], found [%llx + %llx]\n",
+  tmp.start, size,
+  nodes[n].start, nodes[n].size);
+   goto out;
+   }
+   }
}
 
/* After random insertion the nodes should be in order */
@@ -656,17 +681,44 @@ static int igt_insert(void *ignored)
drm_for_each_prime(n, 54) {
u64 size = BIT_ULL(n);
 
-   ret = __igt_insert(count, size - 1);
+   ret = __igt_insert(count, size - 1, false);
if (ret)
return ret;
 
-   ret = __igt_insert(count, size);
+   ret = __igt_insert(count, size, false);
+   if (ret)
+   return ret;
+
+   ret = __igt_insert(count, size + 1, false);
+   }
+
+   return 0;
+}
+
+static int igt_replace(void *ignored)
+{
+   const unsigned int count = min_t(unsigned int, BIT(10), max_iterations);
+   unsigned int n;
+   int ret;
+
+   /* Reuse igt_insert to exercise replacement by inserting a dummy node,
+* then replacing it with the intended node. We want to check that
+* the tree is intact and all the information we need is carried
+* across to the target node.
+*/
+
+   drm_for_each_prime(n, 54) {
+   u64 size = BIT_ULL(n);

[Intel-gfx] [PATCH v2 14/40] drm: kselftest for drm_mm_insert_node_in_range()

2016-12-15 Thread Chris Wilson
Exercise drm_mm_insert_node_in_range(), check that we only allocate from
the specified range.

v2: Use all allocation flags

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/selftests/drm_mm_selftests.h |   1 +
 drivers/gpu/drm/selftests/test-drm_mm.c  | 246 +++
 2 files changed, 247 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index dca726baa65d..92b2c1cb10fa 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -11,3 +11,4 @@ selftest(debug, igt_debug)
 selftest(reserve, igt_reserve)
 selftest(insert, igt_insert)
 selftest(replace, igt_replace)
+selftest(insert_range, igt_insert_range)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index dca146478b06..94cd0741c5b6 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -724,6 +724,252 @@ static int igt_replace(void *ignored)
return 0;
 }
 
+static bool expect_insert_in_range_fail(struct drm_mm *mm,
+   u64 size,
+   u64 range_start,
+   u64 range_end)
+{
+   struct drm_mm_node tmp = {};
+   int err;
+
+   err = drm_mm_insert_node_in_range_generic(mm, ,
+ size, 0, 0,
+ range_start, range_end,
+ DRM_MM_SEARCH_DEFAULT,
+ DRM_MM_CREATE_DEFAULT);
+   if (err != -ENOSPC)  {
+   if (!err) {
+   pr_err("impossible insert succeeded, node %llx + %llu, 
range [%llx, %llx]\n",
+  tmp.start, tmp.size, range_start, range_end);
+   drm_mm_remove_node();
+   } else {
+   pr_err("impossible insert failed with wrong error %d 
[expected %d], size %llu, range [%llx, %llx]\n",
+  err, -ENOSPC, size, range_start, range_end);
+   }
+   return false;
+   }
+
+   return true;
+}
+
+static bool assert_contiguous_in_range(struct drm_mm *mm,
+  u64 size,
+  u64 start,
+  u64 end)
+{
+   struct drm_mm_node *node;
+   unsigned int n;
+
+   if (!expect_insert_in_range_fail(mm, size, start, end))
+   return false;
+
+   n = div64_u64(start + size - 1, size);
+   drm_mm_for_each_node(node, mm) {
+   if (node->start < start || node->start + node->size > end) {
+   pr_err("node %d out of range, address [%llx + %llu], 
range [%llx, %llx]\n",
+  n, node->start, node->start + node->size, start, 
end);
+   return false;
+   }
+
+   if (node->start != n * size) {
+   pr_err("node %d out of order, expected start %llx, 
found %llx\n",
+  n, n * size, node->start);
+   return false;
+   }
+
+   if (node->size != size) {
+   pr_err("node %d has wrong size, expected size %llx, 
found %llx\n",
+  n, size, node->size);
+   return false;
+   }
+
+   if (node->hole_follows && drm_mm_hole_node_end(node) < end) {
+   pr_err("node %d is followed by a hole!\n", n);
+   return false;
+   }
+
+   n++;
+   }
+
+   drm_mm_for_each_node_in_range(node, mm, 0, start) {
+   if (node) {
+   pr_err("node before start: node=%llx+%llu, 
start=%llx\n",
+  node->start, node->size, start);
+   return false;
+   }
+   }
+
+   drm_mm_for_each_node_in_range(node, mm, end, U64_MAX) {
+   if (node) {
+   pr_err("node after end: node=%llx+%llu, end=%llx\n",
+  node->start, node->size, end);
+   return false;
+   }
+   }
+
+   return true;
+}
+
+static int __igt_insert_range(unsigned int count, u64 size, u64 start, u64 end)
+{
+   const struct insert_mode *mode;
+   struct drm_mm mm;
+   struct drm_mm_node *nodes, *node, *next;
+   unsigned int n, start_n, end_n;
+   int ret, err;
+
+   DRM_MM_BUG_ON(!count);
+   DRM_MM_BUG_ON(!size);
+   DRM_MM_BUG_ON(end <= start);
+
+   /* Very similar to __igt_insert(), but now instead of populating the
+* full range of the drm_mm, we try to fill a small portion of it.
+*/
+
+   ret 

[Intel-gfx] [PATCH v2 10/40] drm: kselftest for drm_mm_debug()

2016-12-15 Thread Chris Wilson
Simple test to just exercise calling the debug dumper on the drm_mm.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/selftests/drm_mm_selftests.h |  1 +
 drivers/gpu/drm/selftests/test-drm_mm.c  | 35 
 2 files changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index 844dd29db540..0265f09e92fa 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -7,3 +7,4 @@
  */
 selftest(sanitycheck, igt_sanitycheck) /* keep first (selfcheck for igt) */
 selftest(init, igt_init)
+selftest(debug, igt_debug)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index ccef8e249d37..262e44f8f9fb 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -138,6 +138,41 @@ static int igt_init(void *ignored)
return ret;
 }
 
+static int igt_debug(void *ignored)
+{
+   struct drm_mm mm;
+   struct drm_mm_node nodes[2];
+   int ret;
+
+   /* Create a small drm_mm with a couple of nodes and a few holes, and
+* check that the debug iterator doesn't explode over a trivial drm_mm.
+*/
+
+   drm_mm_init(, 0, 4096);
+
+   memset(nodes, 0, sizeof(nodes));
+   nodes[0].start = 512;
+   nodes[0].size = 1024;
+   ret = drm_mm_reserve_node(, [0]);
+   if (ret) {
+   pr_err("failed to reserve node[0] {start=%lld, size=%lld)\n",
+  nodes[0].start, nodes[0].size);
+   return ret;
+   }
+
+   nodes[1].size = 1024;
+   nodes[1].start = 4096 - 512 - nodes[1].size;
+   ret = drm_mm_reserve_node(, [1]);
+   if (ret) {
+   pr_err("failed to reserve node[1] {start=%lld, size=%lld)\n",
+  nodes[1].start, nodes[1].size);
+   return ret;
+   }
+
+   drm_mm_debug_table(, __func__);
+   return 0;
+}
+
 #include "drm_selftest.c"
 
 static int __init test_drm_mm_init(void)
-- 
2.11.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 38/40] drm: Use drm_mm_insert_node_in_range_generic() for everyone

2016-12-15 Thread Chris Wilson
Remove a superfluous helper as drm_mm_insert_node is equivalent to
insert_node_in_range with a range of (0, U64_MAX).

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/drm_mm.c | 166 ---
 include/drm/drm_mm.h |  90 +++--
 2 files changed, 67 insertions(+), 189 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 062a2a82efd6..c6fce14178cc 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -92,11 +92,6 @@
  * some basic allocator dumpers for debugging.
  */
 
-static struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
-   u64 size,
-   u64 alignment,
-   unsigned long color,
-   enum drm_mm_search_flags flags);
 static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct 
drm_mm *mm,
u64 size,
u64 alignment,
@@ -230,6 +225,7 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
 struct drm_mm_node *node,
 u64 size, u64 alignment,
 unsigned long color,
+u64 range_start, u64 range_end,
 enum drm_mm_allocator_flags flags)
 {
struct drm_mm *mm = hole_node->mm;
@@ -238,11 +234,14 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
u64 adj_start = hole_start;
u64 adj_end = hole_end;
 
-   DRM_MM_BUG_ON(node->allocated);
+   DRM_MM_BUG_ON(!drm_mm_hole_follows(hole_node) || node->allocated);
 
if (mm->color_adjust)
mm->color_adjust(hole_node, color, _start, _end);
 
+   adj_start = max(adj_start, range_start);
+   adj_end = min(adj_end, range_end);
+
if (flags & DRM_MM_CREATE_TOP)
adj_start = adj_end - size;
 
@@ -258,9 +257,6 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
}
}
 
-   DRM_MM_BUG_ON(adj_start < hole_start);
-   DRM_MM_BUG_ON(adj_end > hole_end);
-
if (adj_start == hole_start) {
hole_node->hole_follows = 0;
list_del(_node->hole_stack);
@@ -276,7 +272,10 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
 
drm_mm_interval_tree_add_node(hole_node, node);
 
+   DRM_MM_BUG_ON(node->start < range_start);
+   DRM_MM_BUG_ON(node->start < adj_start);
DRM_MM_BUG_ON(node->start + node->size > adj_end);
+   DRM_MM_BUG_ON(node->start + node->size > range_end);
 
node->hole_follows = 0;
if (__drm_mm_hole_node_start(node) < hole_end) {
@@ -360,107 +359,6 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct 
drm_mm_node *node)
 EXPORT_SYMBOL(drm_mm_reserve_node);
 
 /**
- * drm_mm_insert_node_generic - search for space and insert @node
- * @mm: drm_mm to allocate from
- * @node: preallocate node to insert
- * @size: size of the allocation
- * @alignment: alignment of the allocation
- * @color: opaque tag value to use for this node
- * @sflags: flags to fine-tune the allocation search
- * @aflags: flags to fine-tune the allocation behavior
- *
- * The preallocated node must be cleared to 0.
- *
- * Returns:
- * 0 on success, -ENOSPC if there's no suitable hole.
- */
-int drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node,
-  u64 size, u64 alignment,
-  unsigned long color,
-  enum drm_mm_search_flags sflags,
-  enum drm_mm_allocator_flags aflags)
-{
-   struct drm_mm_node *hole_node;
-
-   if (WARN_ON(size == 0))
-   return -EINVAL;
-
-   hole_node = drm_mm_search_free_generic(mm, size, alignment,
-  color, sflags);
-   if (!hole_node)
-   return -ENOSPC;
-
-   drm_mm_insert_helper(hole_node, node, size, alignment, color, aflags);
-   return 0;
-}
-EXPORT_SYMBOL(drm_mm_insert_node_generic);
-
-static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node,
-  struct drm_mm_node *node,
-  u64 size, u64 alignment,
-  unsigned long color,
-  u64 start, u64 end,
-  enum drm_mm_allocator_flags flags)
-{
-   struct drm_mm *mm = hole_node->mm;
-   u64 hole_start = drm_mm_hole_node_start(hole_node);
-   u64 hole_end = drm_mm_hole_node_end(hole_node);
-   u64 adj_start = hole_start;
-   u64 adj_end = hole_end;
-
-   

[Intel-gfx] [PATCH v2 20/40] drm: kselftest for drm_mm and color eviction

2016-12-15 Thread Chris Wilson
Check that after applying the driver's color adjustment, eviction
scanning find a suitable hole.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/selftests/drm_mm_selftests.h |   1 +
 drivers/gpu/drm/selftests/test-drm_mm.c  | 159 +++
 2 files changed, 160 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index ff44f39a1826..0a3a7e32e5f7 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -19,3 +19,4 @@ selftest(evict, igt_evict)
 selftest(evict_range, igt_evict_range)
 selftest(topdown, igt_topdown)
 selftest(color, igt_color)
+selftest(color_evict, igt_color_evict)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index 6b3af04eb582..0a051abc8f13 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -1830,6 +1830,165 @@ static int igt_color(void *ignored)
return ret;
 }
 
+static int evict_color(struct drm_mm *mm,
+  struct evict_node *nodes,
+  unsigned int *order,
+  unsigned int count,
+  unsigned int size,
+  unsigned int alignment,
+  unsigned long color,
+  const struct insert_mode *mode)
+{
+   LIST_HEAD(evict_list);
+   struct evict_node *e;
+   struct drm_mm_node tmp;
+   int err;
+
+   drm_mm_init_scan(mm, size, alignment, color);
+   if (!evict_nodes(mm,
+nodes, order, count,
+_list))
+   return -EINVAL;
+
+   memset(, 0, sizeof(tmp));
+   err = drm_mm_insert_node_generic(mm, , size, alignment, color,
+mode->search_flags,
+mode->create_flags);
+   if (err) {
+   pr_err("Failed to insert into eviction hole: size=%d, align=%d, 
color=%lu, err=%d\n",
+  size, alignment, color, err);
+   show_scan(mm);
+   show_holes(mm, 3);
+   return err;
+   }
+
+   if (colors_abutt())
+   err = -EINVAL;
+
+   if (!assert_node(, mm, size, alignment, color)) {
+   pr_err("Inserted did not fit the eviction hole: size=%lld [%d], 
align=%d [rem=%lld], start=%llx\n",
+  tmp.size, size,
+  alignment, misaligned(, alignment), tmp.start);
+   err = -EINVAL;
+   }
+
+   drm_mm_remove_node();
+   if (err)
+   return err;
+
+   list_for_each_entry(e, _list, link) {
+   err = drm_mm_reserve_node(mm, >node);
+   if (err) {
+   pr_err("Failed to reinsert node after eviction: 
start=%llx\n",
+  e->node.start);
+   return err;
+   }
+   }
+
+   return 0;
+}
+
+static int igt_color_evict(void *ignored)
+{
+   RND_STATE(prng, random_seed);
+   const unsigned int total_size = min(8192u, max_iterations);
+   const struct insert_mode *mode;
+   unsigned long color = 0;
+   struct drm_mm mm;
+   struct evict_node *nodes;
+   struct drm_mm_node *node, *next;
+   unsigned int *order, n;
+   int ret, err;
+
+   /* Check that the drm_mm_scan also honours color adjustment when
+* choosing its victims to create a hole. Our color_adjust does not
+* allow two nodes to be placed together without an intervening hole
+* enlarging the set of victims that must be evicted.
+*/
+
+   ret = -ENOMEM;
+   nodes = vzalloc(total_size * sizeof(*nodes));
+   if (!nodes)
+   goto err;
+
+   order = drm_random_order(total_size, );
+   if (!order)
+   goto err_nodes;
+
+   ret = -EINVAL;
+   drm_mm_init(, 0, 2*total_size - 1);
+   mm.color_adjust = separate_adjacent_colors;
+   for (n = 0; n < total_size; n++) {
+   err = drm_mm_insert_node_generic(, [n].node,
+1, 0, color++,
+DRM_MM_SEARCH_DEFAULT,
+DRM_MM_CREATE_DEFAULT);
+   if (err) {
+   pr_err("insert failed, step %d\n", n);
+   ret = err;
+   goto out;
+   }
+   }
+
+   for (mode = evict_modes; mode->name; mode++) {
+   for (n = 1; n <= total_size; n <<= 1) {
+   drm_random_reorder(order, total_size, );
+   err = evict_color(,
+ nodes, order, total_size,
+ n, 1, color++,
+ 

[Intel-gfx] [PATCH v2 39/40] drm: Improve drm_mm search (and fix topdown allocation) with rbtrees

2016-12-15 Thread Chris Wilson
The drm_mm range manager claimed to support top-down insertion, but it
was neither searching for the top-most hole that could fit the
allocation request nor fitting the request to the hole correctly.

In order to search the range efficiently, we create a secondary index
for the holes using either their size or their address. This index
allows us to find the smallest hole or the hole at the bottom or top of
the range efficiently, whilst keeping the hole stack to rapidly service
evictions.

v2: Search for holes both high and low. Rename flags to mode.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c  |  16 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c |  20 +-
 drivers/gpu/drm/armada/armada_gem.c  |   4 +-
 drivers/gpu/drm/drm_mm.c | 507 +++
 drivers/gpu/drm/drm_vma_manager.c|   3 +-
 drivers/gpu/drm/etnaviv/etnaviv_mmu.c|   8 +-
 drivers/gpu/drm/i915/i915_gem.c  |  10 +-
 drivers/gpu/drm/i915/i915_gem_evict.c|   9 +-
 drivers/gpu/drm/i915/i915_gem_execbuffer.c   |   5 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c  |  39 +--
 drivers/gpu/drm/i915/i915_gem_stolen.c   |   6 +-
 drivers/gpu/drm/msm/msm_gem.c|   3 +-
 drivers/gpu/drm/msm/msm_gem_vma.c|   3 +-
 drivers/gpu/drm/selftests/test-drm_mm.c  |  97 ++---
 drivers/gpu/drm/sis/sis_mm.c |   6 +-
 drivers/gpu/drm/tegra/gem.c  |   4 +-
 drivers/gpu/drm/ttm/ttm_bo_manager.c |  18 +-
 drivers/gpu/drm/vc4/vc4_crtc.c   |   2 +-
 drivers/gpu/drm/vc4/vc4_hvs.c|   3 +-
 drivers/gpu/drm/vc4/vc4_plane.c  |   6 +-
 drivers/gpu/drm/via/via_mm.c |   4 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c   |  10 +-
 include/drm/drm_mm.h | 135 +++
 23 files changed, 442 insertions(+), 476 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
index 00f46b0e076d..d841fcb2e709 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
@@ -97,8 +97,7 @@ int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man,
 {
struct amdgpu_gtt_mgr *mgr = man->priv;
struct drm_mm_node *node = mem->mm_node;
-   enum drm_mm_search_flags sflags = DRM_MM_SEARCH_BEST;
-   enum drm_mm_allocator_flags aflags = DRM_MM_CREATE_DEFAULT;
+   enum drm_mm_insert_mode mode;
unsigned long fpfn, lpfn;
int r;
 
@@ -115,15 +114,14 @@ int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man,
else
lpfn = man->size;
 
-   if (place && place->flags & TTM_PL_FLAG_TOPDOWN) {
-   sflags = DRM_MM_SEARCH_BELOW;
-   aflags = DRM_MM_CREATE_TOP;
-   }
+   mode = DRM_MM_INSERT_BEST;
+   if (place && place->mode & TTM_PL_FLAG_TOPDOWN)
+   mode = DRM_MM_INSERT_HIGH;
 
spin_lock(>lock);
-   r = drm_mm_insert_node_in_range_generic(>mm, node, mem->num_pages,
-   mem->page_alignment, 0,
-   fpfn, lpfn, sflags, aflags);
+   r = drm_mm_insert_node_in_range(>mm, node,
+   mem->num_pages, mem->page_alignment, 0,
+   fpfn, lpfn, mode);
spin_unlock(>lock);
 
if (!r) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
index d710226a0fff..5f106ad815ce 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -97,8 +97,7 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager 
*man,
struct amdgpu_vram_mgr *mgr = man->priv;
struct drm_mm *mm = >mm;
struct drm_mm_node *nodes;
-   enum drm_mm_search_flags sflags = DRM_MM_SEARCH_DEFAULT;
-   enum drm_mm_allocator_flags aflags = DRM_MM_CREATE_DEFAULT;
+   enum drm_mm_insert_mode mode;
unsigned long lpfn, num_nodes, pages_per_node, pages_left;
unsigned i;
int r;
@@ -121,10 +120,9 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager 
*man,
if (!nodes)
return -ENOMEM;
 
-   if (place->flags & TTM_PL_FLAG_TOPDOWN) {
-   sflags = DRM_MM_SEARCH_BELOW;
-   aflags = DRM_MM_CREATE_TOP;
-   }
+   mode = DRM_MM_INSERT_BEST;
+   if (place->flags & TTM_PL_FLAG_TOPDOWN)
+   mode = DRM_MM_INSERT_HIGH;
 
pages_left = mem->num_pages;
 
@@ -135,13 +133,11 @@ static int amdgpu_vram_mgr_new(struct 
ttm_mem_type_manager *man,
 
if (pages == pages_per_node)
alignment = pages_per_node;
-   else
-   sflags |= DRM_MM_SEARCH_BEST;
 
-   r = 

[Intel-gfx] [PATCH v2 28/40] drm: Extract struct drm_mm_scan from struct drm_mm

2016-12-15 Thread Chris Wilson
The scan state occupies a large proportion of the struct drm_mm and is
rarely used and only contains temporary state. That makes it suitable to
moving to its struct and onto the stack of the callers.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c| 124 ++--
 drivers/gpu/drm/etnaviv/etnaviv_mmu.c   |   7 +-
 drivers/gpu/drm/i915/i915_gem_evict.c   |  19 +++--
 drivers/gpu/drm/selftests/test-drm_mm.c |  45 ++--
 include/drm/drm_mm.h|  43 +++
 5 files changed, 138 insertions(+), 100 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 57267845b7d4..0f1396b0d39a 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -574,7 +574,7 @@ static struct drm_mm_node *drm_mm_search_free_generic(const 
struct drm_mm *mm,
u64 adj_end;
u64 best_size;
 
-   DRM_MM_BUG_ON(mm->scanned_blocks);
+   DRM_MM_BUG_ON(mm->scan_active);
 
best = NULL;
best_size = ~0UL;
@@ -618,7 +618,7 @@ static struct drm_mm_node 
*drm_mm_search_free_in_range_generic(const struct drm_
u64 adj_end;
u64 best_size;
 
-   DRM_MM_BUG_ON(mm->scanned_blocks);
+   DRM_MM_BUG_ON(mm->scan_active);
 
best = NULL;
best_size = ~0UL;
@@ -693,7 +693,7 @@ EXPORT_SYMBOL(drm_mm_replace_node);
  *
  * The DRM range allocator supports this use-case through the scanning
  * interfaces. First a scan operation needs to be initialized with
- * drm_mm_init_scan() or drm_mm_init_scan_with_range(). The driver adds
+ * drm_mm_scan_init() or drm_mm_scan_init_with_range(). The driver adds
  * objects to the roaster (probably by walking an LRU list, but this can be
  * freely implemented) until a suitable hole is found or there's no further
  * evictable object.
@@ -710,7 +710,8 @@ EXPORT_SYMBOL(drm_mm_replace_node);
  */
 
 /**
- * drm_mm_init_scan - initialize lru scanning
+ * drm_mm_scan_init - initialize lru scanning
+ * @scan: scan state
  * @mm: drm_mm to scan
  * @size: size of the allocation
  * @alignment: alignment of the allocation
@@ -724,26 +725,33 @@ EXPORT_SYMBOL(drm_mm_replace_node);
  * As long as the scan list is non-empty, no other operations than
  * adding/removing nodes to/from the scan list are allowed.
  */
-void drm_mm_init_scan(struct drm_mm *mm,
+void drm_mm_scan_init(struct drm_mm_scan *scan,
+ struct drm_mm *mm,
  u64 size,
  u64 alignment,
  unsigned long color)
 {
DRM_MM_BUG_ON(size == 0);
+   DRM_MM_BUG_ON(mm->scan_active);
 
-   mm->scan_color = color;
-   mm->scan_alignment = alignment;
-   mm->scan_size = size;
-   mm->scanned_blocks = 0;
-   mm->scan_hit_start = 0;
-   mm->scan_hit_end = 0;
-   mm->scan_check_range = 0;
-   mm->prev_scanned_node = NULL;
+   scan->mm = mm;
+
+   scan->color = color;
+   scan->alignment = alignment;
+   scan->size = size;
+
+   scan->check_range = 0;
+
+   scan->hit_start = U64_MAX;
+   scan->hit_end = 0;
+
+   scan->prev_scanned_node = NULL;
 }
-EXPORT_SYMBOL(drm_mm_init_scan);
+EXPORT_SYMBOL(drm_mm_scan_init);
 
 /**
- * drm_mm_init_scan - initialize range-restricted lru scanning
+ * drm_mm_scan_init_with_range - initialize range-restricted lru scanning
+ * @scan: scan state
  * @mm: drm_mm to scan
  * @size: size of the allocation
  * @alignment: alignment of the allocation
@@ -759,7 +767,8 @@ EXPORT_SYMBOL(drm_mm_init_scan);
  * As long as the scan list is non-empty, no other operations than
  * adding/removing nodes to/from the scan list are allowed.
  */
-void drm_mm_init_scan_with_range(struct drm_mm *mm,
+void drm_mm_scan_init_with_range(struct drm_mm_scan *scan,
+struct drm_mm *mm,
 u64 size,
 u64 alignment,
 unsigned long color,
@@ -768,19 +777,25 @@ void drm_mm_init_scan_with_range(struct drm_mm *mm,
 {
DRM_MM_BUG_ON(start >= end);
DRM_MM_BUG_ON(size == 0 || size > end - start);
+   DRM_MM_BUG_ON(mm->scan_active);
+
+   scan->mm = mm;
+
+   scan->color = color;
+   scan->alignment = alignment;
+   scan->size = size;
+
+   DRM_MM_BUG_ON(end <= start);
+   scan->range_start = start;
+   scan->range_end = end;
+   scan->check_range = 1;
 
-   mm->scan_color = color;
-   mm->scan_alignment = alignment;
-   mm->scan_size = size;
-   mm->scanned_blocks = 0;
-   mm->scan_hit_start = 0;
-   mm->scan_hit_end = 0;
-   mm->scan_start = start;
-   mm->scan_end = end;
-   mm->scan_check_range = 1;
-   mm->prev_scanned_node = NULL;
+   scan->hit_start = U64_MAX;
+   scan->hit_end = 0;
+
+   scan->prev_scanned_node = NULL;
 }

[Intel-gfx] [PATCH v2 07/40] drm: Add a simple generator of random permutations

2016-12-15 Thread Chris Wilson
When testing, we want a random but yet reproducible order in which to
process elements. Here we create an array which is a random (using the
Tausworthe PRNG) permutation of the order in which to execute.

v2: Tidier code by David Herrmann

Signed-off-by: Chris Wilson 
Cc: Joonas Lahtinen 
Cc: David Herrmann 
---
 drivers/gpu/drm/Kconfig  |  6 ++
 drivers/gpu/drm/Makefile |  1 +
 drivers/gpu/drm/lib/drm_random.c | 41 
 drivers/gpu/drm/lib/drm_random.h | 21 
 4 files changed, 69 insertions(+)
 create mode 100644 drivers/gpu/drm/lib/drm_random.c
 create mode 100644 drivers/gpu/drm/lib/drm_random.h

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index d1363d21d3d1..2e6ae95459e4 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -52,6 +52,7 @@ config DRM_DEBUG_MM_SELFTEST
tristate "kselftests for DRM range manager (struct drm_mm)"
depends on DRM
depends on DEBUG_KERNEL
+   select DRM_LIB_RANDOM
default n
help
  This option provides a kernel module that can be used to test
@@ -334,3 +335,8 @@ config DRM_SAVAGE
  chipset. If M is selected the module will be called savage.
 
 endif # DRM_LEGACY
+
+config DRM_LIB_RANDOM
+   bool
+   default n
+
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index c8aed3688b20..0fa16275fdae 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -18,6 +18,7 @@ drm-y   :=drm_auth.o drm_bufs.o drm_cache.o \
drm_plane.o drm_color_mgmt.o drm_print.o \
drm_dumb_buffers.o drm_mode_config.o
 
+drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
 obj-$(CONFIG_DRM_DEBUG_MM_SELFTEST) += selftests/test-drm_mm.o
 
 drm-$(CONFIG_COMPAT) += drm_ioc32.o
diff --git a/drivers/gpu/drm/lib/drm_random.c b/drivers/gpu/drm/lib/drm_random.c
new file mode 100644
index ..507e72721b6f
--- /dev/null
+++ b/drivers/gpu/drm/lib/drm_random.c
@@ -0,0 +1,41 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "drm_random.h"
+
+static inline u32 prandom_u32_max_state(u32 ep_ro, struct rnd_state *state)
+{
+   return upper_32_bits((u64)prandom_u32_state(state) * ep_ro);
+}
+
+void drm_random_reorder(unsigned int *order, unsigned int count,
+   struct rnd_state *state)
+{
+   unsigned int i, j;
+
+   for (i = 0; i < count; ++i) {
+   BUILD_BUG_ON(sizeof(unsigned int) > sizeof(u32));
+   j = prandom_u32_max_state(count, state);
+   swap(order[i], order[j]);
+   }
+}
+EXPORT_SYMBOL(drm_random_reorder);
+
+unsigned int *drm_random_order(unsigned int count, struct rnd_state *state)
+{
+   unsigned int *order, i;
+
+   order = kmalloc_array(count, sizeof(*order), GFP_TEMPORARY);
+   if (!order)
+   return order;
+
+   for (i = 0; i < count; i++)
+   order[i] = i;
+
+   drm_random_reorder(order, count, state);
+   return order;
+}
+EXPORT_SYMBOL(drm_random_order);
diff --git a/drivers/gpu/drm/lib/drm_random.h b/drivers/gpu/drm/lib/drm_random.h
new file mode 100644
index ..931c8f4a261d
--- /dev/null
+++ b/drivers/gpu/drm/lib/drm_random.h
@@ -0,0 +1,21 @@
+#ifndef __DRM_RANDOM_H__
+#define __DRM_RANDOM_H
+
+#include 
+
+#define RND_STATE_INITIALIZER(seed__) ({   \
+   struct rnd_state state__;   \
+   prandom_seed_state(__, (seed__)); \
+   state__;\
+})
+
+#define RND_STATE(name__, seed__) \
+   struct rnd_state name__ = RND_STATE_INITIALIZER(seed__)
+
+unsigned int *drm_random_order(unsigned int count,
+  struct rnd_state *state);
+void drm_random_reorder(unsigned int *order,
+   unsigned int count,
+   struct rnd_state *state);
+
+#endif /* __DRM_RANDOM_H__ */
-- 
2.11.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 36/40] drm: Wrap drm_mm_node.hole_follows

2016-12-15 Thread Chris Wilson
Insulate users from changed to the internal hole tracking within
struct drm_mm_node by using an accessor for hole_follows.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/drm_mm.c| 12 ++--
 drivers/gpu/drm/i915/i915_vma.c |  4 ++--
 drivers/gpu/drm/selftests/test-drm_mm.c | 18 ++
 include/drm/drm_mm.h| 22 +++---
 4 files changed, 37 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 22db356e3ebc..da9f98690e97 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -323,7 +323,7 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct 
drm_mm_node *node)
}
 
hole = list_last_entry(>node_list, typeof(*hole), node_list);
-   if (!hole->hole_follows)
+   if (!drm_mm_hole_follows(hole))
return -ENOSPC;
 
adj_start = hole_start = __drm_mm_hole_node_start(hole);
@@ -408,7 +408,7 @@ static void drm_mm_insert_helper_range(struct drm_mm_node 
*hole_node,
u64 adj_start = hole_start;
u64 adj_end = hole_end;
 
-   DRM_MM_BUG_ON(!hole_node->hole_follows || node->allocated);
+   DRM_MM_BUG_ON(!drm_mm_hole_follows(hole_node) || node->allocated);
 
if (adj_start < start)
adj_start = start;
@@ -523,16 +523,16 @@ void drm_mm_remove_node(struct drm_mm_node *node)
prev_node =
list_entry(node->node_list.prev, struct drm_mm_node, node_list);
 
-   if (node->hole_follows) {
+   if (drm_mm_hole_follows(node)) {
DRM_MM_BUG_ON(__drm_mm_hole_node_start(node) ==
  __drm_mm_hole_node_end(node));
list_del(>hole_stack);
-   } else
+   } else {
DRM_MM_BUG_ON(__drm_mm_hole_node_start(node) !=
  __drm_mm_hole_node_end(node));
+   }
 
-
-   if (!prev_node->hole_follows) {
+   if (!drm_mm_hole_follows(prev_node)) {
prev_node->hole_follows = 1;
list_add(_node->hole_stack, >hole_stack);
} else
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index f709c9b76358..34374c4133b5 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -322,11 +322,11 @@ bool i915_gem_valid_gtt_space(struct i915_vma *vma, 
unsigned long cache_level)
GEM_BUG_ON(list_empty(>node_list));
 
other = list_prev_entry(node, node_list);
-   if (color_differs(other, cache_level) && !other->hole_follows)
+   if (color_differs(other, cache_level) && !drm_mm_hole_follows(other))
return false;
 
other = list_next_entry(node, node_list);
-   if (color_differs(other, cache_level) && !node->hole_follows)
+   if (color_differs(other, cache_level) && !drm_mm_hole_follows(node))
return false;
 
return true;
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index 9899e8364350..a9ed018aac12 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -42,7 +42,7 @@ static bool assert_no_holes(const struct drm_mm *mm)
}
 
drm_mm_for_each_node(hole, mm) {
-   if (hole->hole_follows) {
+   if (drm_mm_hole_follows(hole)) {
pr_err("Hole follows node, expected none!\n");
return false;
}
@@ -104,7 +104,7 @@ static bool assert_continuous(const struct drm_mm *mm, u64 
size)
return false;
}
 
-   if (node->hole_follows) {
+   if (drm_mm_hole_follows(node)) {
pr_err("node[%ld] is followed by a hole!\n", n);
return false;
}
@@ -787,7 +787,8 @@ static bool assert_contiguous_in_range(struct drm_mm *mm,
return false;
}
 
-   if (node->hole_follows && drm_mm_hole_node_end(node) < end) {
+   if (drm_mm_hole_follows(node) &&
+   drm_mm_hole_node_end(node) < end) {
pr_err("node %d is followed by a hole!\n", n);
return false;
}
@@ -1307,11 +1308,12 @@ static int evict_something(struct drm_mm *mm,
err = -EINVAL;
}
 
-   if (!assert_node(, mm, size, alignment, 0) || tmp.hole_follows) {
+   if (!assert_node(, mm, size, alignment, 0) ||
+   drm_mm_hole_follows()) {
pr_err("Inserted did not fill the eviction hole: size=%lld 
[%d], align=%d [rem=%lld], start=%llx, hole-follows?=%d\n",
   tmp.size, size,
   alignment, misaligned(, alignment),
-  tmp.start, tmp.hole_follows);
+  tmp.start, drm_mm_hole_follows());
err = 

[Intel-gfx] [PATCH v2 32/40] drm: Compute tight evictions for drm_mm_scan

2016-12-15 Thread Chris Wilson
Compute the minimal required hole during scan and only evict those nodes
that overlap. This enables us to reduce the number of nodes we need to
evict to the bare minimum.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c| 60 +++--
 drivers/gpu/drm/etnaviv/etnaviv_mmu.c   |  2 +-
 drivers/gpu/drm/i915/i915_gem_evict.c   |  3 +-
 drivers/gpu/drm/selftests/test-drm_mm.c | 10 +++---
 include/drm/drm_mm.h| 22 ++--
 5 files changed, 71 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 956782e7b092..ff1e62c066e8 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -718,10 +718,10 @@ EXPORT_SYMBOL(drm_mm_replace_node);
  * @color: opaque tag value to use for the allocation
  * @start: start of the allowed range for the allocation
  * @end: end of the allowed range for the allocation
+ * @flags: flags to specify how the allocation will be performed afterwards
  *
  * This simply sets up the scanning routines with the parameters for the 
desired
- * hole. Note that there's no need to specify allocation flags, since they only
- * change the place a node is allocated from within a suitable hole.
+ * hole.
  *
  * Warning:
  * As long as the scan list is non-empty, no other operations than
@@ -733,7 +733,8 @@ void drm_mm_scan_init_with_range(struct drm_mm_scan *scan,
 u64 alignment,
 unsigned long color,
 u64 start,
-u64 end)
+u64 end,
+unsigned int flags)
 {
DRM_MM_BUG_ON(start >= end);
DRM_MM_BUG_ON(size == 0 || size > end - start);
@@ -744,6 +745,7 @@ void drm_mm_scan_init_with_range(struct drm_mm_scan *scan,
scan->color = color;
scan->alignment = alignment;
scan->size = size;
+   scan->flags = flags;
 
DRM_MM_BUG_ON(end <= start);
scan->range_start = start;
@@ -778,7 +780,7 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
DRM_MM_BUG_ON(node->mm != mm);
DRM_MM_BUG_ON(!node->allocated);
DRM_MM_BUG_ON(node->scanned_block);
-   node->scanned_block = 1;
+   node->scanned_block = true;
mm->scan_active++;
 
hole = list_prev_entry(node, node_list);
@@ -800,15 +802,53 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
 
adj_start = max(col_start, scan->range_start);
adj_end = min(col_end, scan->range_end);
+   if (adj_end <= adj_start || adj_end - adj_start < scan->size)
+   return false;
+
+   if (scan->flags == DRM_MM_CREATE_TOP)
+   adj_start = adj_end - scan->size;
+
+   if (scan->alignment) {
+   u64 rem;
+
+   div64_u64_rem(adj_start, scan->alignment, );
+   if (rem) {
+   adj_start -= rem;
+   if (scan->flags != DRM_MM_CREATE_TOP)
+   adj_start += scan->alignment;
+   if (adj_start < max(col_start, scan->range_start) ||
+   min(col_end, scan->range_end) - adj_start < 
scan->size)
+   return false;
+
+   if (adj_end <= adj_start ||
+   adj_end - adj_start < scan->size)
+   return false;
+   }
+   }
 
-   if (check_free_hole(adj_start, adj_end,
-   scan->size, scan->alignment)) {
+   if (mm->color_adjust) {
+   /* If allocations need adjusting due to neighbouring colours,
+* we do not have enough information to decide if we need
+* to evict nodes on either side of [adj_start, adj_end].
+* What almost works is
+* hit_start = adj_start + (hole_start - col_start);
+* hit_end = adj_start + scan->size + (hole_end - col_end);
+* but because the decision is only made on the final hole,
+* we may underestimate the required adjustments for an
+* interior allocation.
+*/
scan->hit_start = hole_start;
scan->hit_end = hole_end;
-   return true;
+   } else {
+   scan->hit_start = adj_start;
+   scan->hit_end = adj_start + scan->size;
}
 
-   return false;
+   DRM_MM_BUG_ON(scan->hit_start >= scan->hit_end);
+   DRM_MM_BUG_ON(scan->hit_start < hole_start);
+   DRM_MM_BUG_ON(scan->hit_end > hole_end);
+
+   return true;
 }
 EXPORT_SYMBOL(drm_mm_scan_add_block);
 
@@ -836,7 +876,7 @@ bool drm_mm_scan_remove_block(struct drm_mm_scan *scan,
 
DRM_MM_BUG_ON(node->mm != scan->mm);

[Intel-gfx] [PATCH v2 21/40] drm: kselftest for drm_mm and restricted color eviction

2016-12-15 Thread Chris Wilson
Check that after applying the driver's color adjustment, restricted
eviction scanning find a suitable hole.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/selftests/drm_mm_selftests.h |   1 +
 drivers/gpu/drm/selftests/test-drm_mm.c  | 119 ++-
 2 files changed, 116 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index 0a3a7e32e5f7..6a4575fdc1c0 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -20,3 +20,4 @@ selftest(evict_range, igt_evict_range)
 selftest(topdown, igt_topdown)
 selftest(color, igt_color)
 selftest(color_evict, igt_color_evict)
+selftest(color_evict_range, igt_color_evict_range)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index 0a051abc8f13..43575074eca5 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -1831,6 +1831,7 @@ static int igt_color(void *ignored)
 }
 
 static int evict_color(struct drm_mm *mm,
+  u64 range_start, u64 range_end,
   struct evict_node *nodes,
   unsigned int *order,
   unsigned int count,
@@ -1844,7 +1845,9 @@ static int evict_color(struct drm_mm *mm,
struct drm_mm_node tmp;
int err;
 
-   drm_mm_init_scan(mm, size, alignment, color);
+   drm_mm_init_scan_with_range(mm,
+   size, alignment, color,
+   range_start, range_end);
if (!evict_nodes(mm,
 nodes, order, count,
 _list))
@@ -1862,6 +1865,12 @@ static int evict_color(struct drm_mm *mm,
return err;
}
 
+   if (tmp.start < range_start || tmp.start + tmp.size > range_end) {
+   pr_err("Inserted [address=%llu + %llu] did not fit into the 
request range [%llu, %llu]\n",
+  tmp.start, tmp.size, range_start, range_end);
+   err = -EINVAL;
+   }
+
if (colors_abutt())
err = -EINVAL;
 
@@ -1933,7 +1942,7 @@ static int igt_color_evict(void *ignored)
for (mode = evict_modes; mode->name; mode++) {
for (n = 1; n <= total_size; n <<= 1) {
drm_random_reorder(order, total_size, );
-   err = evict_color(,
+   err = evict_color(, 0, U64_MAX,
  nodes, order, total_size,
  n, 1, color++,
  mode);
@@ -1946,7 +1955,7 @@ static int igt_color_evict(void *ignored)
 
for (n = 1; n < total_size; n <<= 1) {
drm_random_reorder(order, total_size, );
-   err = evict_color(,
+   err = evict_color(, 0, U64_MAX,
  nodes, order, total_size,
  total_size/2, n, color++,
  mode);
@@ -1963,7 +1972,7 @@ static int igt_color_evict(void *ignored)
DRM_MM_BUG_ON(!nsize);
 
drm_random_reorder(order, total_size, );
-   err = evict_color(,
+   err = evict_color(, 0, U64_MAX,
  nodes, order, total_size,
  nsize, n, color++,
  mode);
@@ -1989,6 +1998,108 @@ static int igt_color_evict(void *ignored)
return ret;
 }
 
+static int igt_color_evict_range(void *ignored)
+{
+   RND_STATE(prng, random_seed);
+   const unsigned int total_size = 8192;
+   const unsigned int range_size = total_size / 2;
+   const unsigned int range_start = total_size / 4;
+   const unsigned int range_end = range_start + range_size;
+   const struct insert_mode *mode;
+   unsigned long color = 0;
+   struct drm_mm mm;
+   struct evict_node *nodes;
+   struct drm_mm_node *node, *next;
+   unsigned int *order, n;
+   int ret, err;
+
+   /* Like igt_color_evict(), but limited to small portion of the full
+* drm_mm range.
+*/
+
+   ret = -ENOMEM;
+   nodes = vzalloc(total_size * sizeof(*nodes));
+   if (!nodes)
+   goto err;
+
+   order = drm_random_order(total_size, );
+   if (!order)
+   goto err_nodes;
+
+   ret = -EINVAL;
+   drm_mm_init(, 0, 2*total_size - 1);
+   mm.color_adjust = separate_adjacent_colors;
+   for (n = 0; n < total_size; n++) {
+   err = drm_mm_insert_node_generic(, [n].node,
+1, 0, color++,
+

[Intel-gfx] [PATCH v2 11/40] drm: kselftest for drm_mm_reserve_node()

2016-12-15 Thread Chris Wilson
Exercise drm_mm_reserve_node(), check that we can't reserve an already
occupied range and that the lists are correct after reserving/removing.

v2: Check for invalid node reservation.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/selftests/drm_mm_selftests.h |   1 +
 drivers/gpu/drm/selftests/test-drm_mm.c  | 279 +++
 2 files changed, 280 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index 0265f09e92fa..693d85677e7f 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -8,3 +8,4 @@
 selftest(sanitycheck, igt_sanitycheck) /* keep first (selfcheck for igt) */
 selftest(init, igt_init)
 selftest(debug, igt_debug)
+selftest(reserve, igt_reserve)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index 262e44f8f9fb..2e40f94cb9d3 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -11,6 +11,9 @@
 
 #include 
 
+#include "../lib/drm_random.h"
+#include "../lib/drm_prime_numbers.h"
+
 #define TESTS "drm_mm_selftests.h"
 #include "drm_selftest.h"
 
@@ -77,6 +80,57 @@ static bool assert_one_hole(const struct drm_mm *mm, u64 
start, u64 end)
return ok;
 }
 
+static bool assert_continuous(const struct drm_mm *mm, u64 size)
+{
+   struct drm_mm_node *node, *check, *found;
+   unsigned long n;
+   u64 addr;
+
+   if (!assert_no_holes(mm))
+   return false;
+
+   n = 0;
+   addr = 0;
+   drm_mm_for_each_node(node, mm) {
+   if (node->start != addr) {
+   pr_err("node[%ld] list out of order, expected %llx 
found %llx\n",
+  n, addr, node->start);
+   return false;
+   }
+
+   if (node->size != size) {
+   pr_err("node[%ld].size incorrect, expected %llx, found 
%llx\n",
+  n, size, node->size);
+   return false;
+   }
+
+   if (node->hole_follows) {
+   pr_err("node[%ld] is followed by a hole!\n", n);
+   return false;
+   }
+
+   found = NULL;
+   drm_mm_for_each_node_in_range(check, mm, addr, addr + size) {
+   if (node != check) {
+   pr_err("lookup return wrong node, expected 
start %llx, found %llx\n",
+  node->start, check->start);
+   return false;
+   }
+   found = check;
+   }
+   if (!found) {
+   pr_err("lookup failed for node %llx + %llx\n",
+  addr, size);
+   return false;
+   }
+
+   addr += size;
+   n++;
+   }
+
+   return true;
+}
+
 static int igt_init(void *ignored)
 {
const unsigned int size = 4096;
@@ -173,6 +227,231 @@ static int igt_debug(void *ignored)
return 0;
 }
 
+static struct drm_mm_node *set_node(struct drm_mm_node *node,
+   u64 start, u64 size)
+{
+   node->start = start;
+   node->size = size;
+   return node;
+}
+
+static bool expect_reserve_fail(struct drm_mm *mm, struct drm_mm_node *node)
+{
+   int err;
+
+   err = drm_mm_reserve_node(mm, node);
+   if (err != -ENOSPC) {
+   if (!err) {
+   pr_err("impossible reserve succeeded, node %llu + 
%llu\n",
+  node->start, node->size);
+   drm_mm_remove_node(node);
+   } else {
+   pr_err("impossible reserve failed with wrong error %d 
[expected %d], node %llu + %llu\n",
+  err, -ENOSPC, node->start, node->size);
+   }
+   return false;
+   }
+
+   return true;
+}
+
+static bool check_reserve_boundaries(struct drm_mm *mm,
+unsigned int count,
+u64 size)
+{
+   const struct boundary {
+   u64 start, size;
+   const char *name;
+   } boundaries[] = {
+#define B(st, sz) { (st), (sz), "{ " #st ", " #sz "}" }
+   B(0, 0),
+   B(-size, 0),
+   B(size, 0),
+   B(size * count, 0),
+   B(-size, size),
+   B(-size, -size),
+   B(-size, 2*size),
+   B(0, -size),
+   B(size, -size),
+   B(count*size, size),
+   B(count*size, -size),
+   B(count*size, count*size),
+   B(count*size, -count*size),
+   

[Intel-gfx] [PATCH v2 23/40] drm: Promote drm_mm alignment to u64

2016-12-15 Thread Chris Wilson
In places (e.g. i915.ko), the alignment is exported to userspace as u64
and there now exists hardware for which we can indeed utilize a u64
alignment. As such, we need to keep 64bit integers throughout when
handling alignment.

Testcase: igt/drm_mm/align64
Testcase: igt/gem_exec_alignment
Signed-off-by: Chris Wilson 
Cc: Joonas Lahtinen 
Cc: Christian König 
Reviewed-by: Christian König 
---
 drivers/gpu/drm/drm_mm.c| 37 +++--
 drivers/gpu/drm/selftests/test-drm_mm.c |  4 ++--
 include/drm/drm_mm.h| 16 +++---
 3 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 2b76167ef39f..2d02ab0925a9 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -93,12 +93,12 @@
 
 static struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
u64 size,
-   unsigned alignment,
+   u64 alignment,
unsigned long color,
enum drm_mm_search_flags flags);
 static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct 
drm_mm *mm,
u64 size,
-   unsigned alignment,
+   u64 alignment,
unsigned long color,
u64 start,
u64 end,
@@ -227,7 +227,7 @@ static void drm_mm_interval_tree_add_node(struct 
drm_mm_node *hole_node,
 
 static void drm_mm_insert_helper(struct drm_mm_node *hole_node,
 struct drm_mm_node *node,
-u64 size, unsigned alignment,
+u64 size, u64 alignment,
 unsigned long color,
 enum drm_mm_allocator_flags flags)
 {
@@ -246,10 +246,9 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
adj_start = adj_end - size;
 
if (alignment) {
-   u64 tmp = adj_start;
-   unsigned rem;
+   u64 rem;
 
-   rem = do_div(tmp, alignment);
+   div64_u64_rem(adj_start, alignment, );
if (rem) {
if (flags & DRM_MM_CREATE_TOP)
adj_start -= rem;
@@ -376,7 +375,7 @@ EXPORT_SYMBOL(drm_mm_reserve_node);
  * 0 on success, -ENOSPC if there's no suitable hole.
  */
 int drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node,
-  u64 size, unsigned alignment,
+  u64 size, u64 alignment,
   unsigned long color,
   enum drm_mm_search_flags sflags,
   enum drm_mm_allocator_flags aflags)
@@ -398,7 +397,7 @@ EXPORT_SYMBOL(drm_mm_insert_node_generic);
 
 static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node,
   struct drm_mm_node *node,
-  u64 size, unsigned alignment,
+  u64 size, u64 alignment,
   unsigned long color,
   u64 start, u64 end,
   enum drm_mm_allocator_flags flags)
@@ -423,10 +422,9 @@ static void drm_mm_insert_helper_range(struct drm_mm_node 
*hole_node,
adj_start = adj_end - size;
 
if (alignment) {
-   u64 tmp = adj_start;
-   unsigned rem;
+   u64 rem;
 
-   rem = do_div(tmp, alignment);
+   div64_u64_rem(adj_start, alignment, );
if (rem) {
if (flags & DRM_MM_CREATE_TOP)
adj_start -= rem;
@@ -482,7 +480,7 @@ static void drm_mm_insert_helper_range(struct drm_mm_node 
*hole_node,
  * 0 on success, -ENOSPC if there's no suitable hole.
  */
 int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, struct drm_mm_node 
*node,
-   u64 size, unsigned alignment,
+   u64 size, u64 alignment,
unsigned long color,
u64 start, u64 end,
enum drm_mm_search_flags sflags,
@@ -548,16 +546,15 @@ void drm_mm_remove_node(struct drm_mm_node *node)
 }
 EXPORT_SYMBOL(drm_mm_remove_node);
 
-static int check_free_hole(u64 

[Intel-gfx] [PATCH v2 17/40] drm: kselftest for drm_mm and range restricted eviction

2016-12-15 Thread Chris Wilson
Check that we add arbitrary blocks to a restrited eviction scanner in
order to find the first minimal hole that matches our request.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/selftests/drm_mm_selftests.h |   1 +
 drivers/gpu/drm/selftests/test-drm_mm.c  | 113 ++-
 2 files changed, 110 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index a31b4458c7eb..965aca65c160 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -16,3 +16,4 @@ selftest(align, igt_align)
 selftest(align32, igt_align32)
 selftest(align64, igt_align64)
 selftest(evict, igt_evict)
+selftest(evict_range, igt_evict_range)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index 4881752d6424..6c4679304358 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -1249,6 +1249,7 @@ static bool evict_everything(struct drm_mm *mm,
 }
 
 static int evict_something(struct drm_mm *mm,
+  u64 range_start, u64 range_end,
   struct evict_node *nodes,
   unsigned int *order,
   unsigned int count,
@@ -1261,7 +1262,9 @@ static int evict_something(struct drm_mm *mm,
struct drm_mm_node tmp;
int err;
 
-   drm_mm_init_scan(mm, size, alignment, 0);
+   drm_mm_init_scan_with_range(mm,
+   size, alignment, 0,
+   range_start, range_end);
if (!evict_nodes(mm,
 nodes, order, count,
 _list))
@@ -1279,6 +1282,12 @@ static int evict_something(struct drm_mm *mm,
return err;
}
 
+   if (tmp.start < range_start || tmp.start + tmp.size > range_end) {
+   pr_err("Inserted [address=%llu + %llu] did not fit into the 
request range [%llu, %llu]\n",
+  tmp.start, tmp.size, range_start, range_end);
+   err = -EINVAL;
+   }
+
if (!assert_node(, mm, size, alignment, 0) || tmp.hole_follows) {
pr_err("Inserted did not fill the eviction hole: size=%lld 
[%d], align=%d [rem=%lld], start=%llx, hole-follows?=%d\n",
   tmp.size, size,
@@ -1360,7 +1369,7 @@ static int igt_evict(void *ignored)
for (mode = evict_modes; mode->name; mode++) {
for (n = 1; n <= size; n <<= 1) {
drm_random_reorder(order, size, );
-   err = evict_something(,
+   err = evict_something(, 0, U64_MAX,
  nodes, order, size,
  n, 1,
  mode);
@@ -1374,7 +1383,7 @@ static int igt_evict(void *ignored)
 
for (n = 1; n < size; n <<= 1) {
drm_random_reorder(order, size, );
-   err = evict_something(,
+   err = evict_something(, 0, U64_MAX,
  nodes, order, size,
  size/2, n,
  mode);
@@ -1392,7 +1401,7 @@ static int igt_evict(void *ignored)
DRM_MM_BUG_ON(!nsize);
 
drm_random_reorder(order, size, );
-   err = evict_something(,
+   err = evict_something(, 0, U64_MAX,
  nodes, order, size,
  nsize, n,
  mode);
@@ -1417,6 +1426,102 @@ static int igt_evict(void *ignored)
return ret;
 }
 
+static int igt_evict_range(void *ignored)
+{
+   RND_STATE(prng, random_seed);
+   const unsigned int size = 8192;
+   const unsigned int range_size = size / 2;
+   const unsigned int range_start = size / 4;
+   const unsigned int range_end = range_start + range_size;
+   const struct insert_mode *mode;
+   struct drm_mm mm;
+   struct evict_node *nodes;
+   struct drm_mm_node *node, *next;
+   unsigned int *order, n;
+   int ret, err;
+
+   /* Like igt_evict() but now we are limiting the search to a
+* small portion of the full drm_mm.
+*/
+
+   ret = -ENOMEM;
+   nodes = vzalloc(size * sizeof(*nodes));
+   if (!nodes)
+   goto err;
+
+   order = drm_random_order(size, );
+   if (!order)
+   goto err_nodes;
+
+   ret = -EINVAL;
+   drm_mm_init(, 0, size);
+   for (n = 0; n < size; n++) {
+   err = drm_mm_insert_node(, [n].node, 1, 0,
+   

[Intel-gfx] [PATCH v2 34/40] drm: Simplify drm_mm scan-list manipulation

2016-12-15 Thread Chris Wilson
Since we mandate a strict reverse-order of drm_mm_scan_remove_block()
after drm_mm_scan_add_block() we can further simplify the list
manipulations when generating the temporary scan-hole.

v2: Highlight the games being played with the lists to track the scan
holes without allocation.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/drm_mm.c | 35 ++-
 include/drm/drm_mm.h |  7 +--
 2 files changed, 19 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index ffa439b2bd2c..91c89ae09b26 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -518,9 +518,7 @@ void drm_mm_remove_node(struct drm_mm_node *node)
struct drm_mm_node *prev_node;
 
DRM_MM_BUG_ON(!node->allocated);
-   DRM_MM_BUG_ON(node->scanned_block ||
- node->scanned_prev_free ||
- node->scanned_next_free);
+   DRM_MM_BUG_ON(node->scanned_block);
 
prev_node =
list_entry(node->node_list.prev, struct drm_mm_node, node_list);
@@ -757,8 +755,6 @@ void drm_mm_scan_init_with_range(struct drm_mm_scan *scan,
 
scan->hit_start = U64_MAX;
scan->hit_end = 0;
-
-   scan->prev_scanned_node = NULL;
 }
 EXPORT_SYMBOL(drm_mm_scan_init_with_range);
 
@@ -787,14 +783,14 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
node->scanned_block = true;
mm->scan_active++;
 
+   /* Remove this block from the node_list so that we enlarge the hole
+* (distance between the end of our previous node and the start of
+* or next), without poisoning the link so that we can restore it
+* later in drm_mm_scan_remove_block().
+*/
hole = list_prev_entry(node, node_list);
-
-   node->scanned_preceeds_hole = hole->hole_follows;
-   hole->hole_follows = 1;
-   list_del(>node_list);
-   node->node_list.prev = >node_list;
-   node->node_list.next = >prev_scanned_node->node_list;
-   scan->prev_scanned_node = node;
+   DRM_MM_BUG_ON(list_next_entry(hole, node_list) != node);
+   __list_del_entry(>node_list);
 
hole_start = __drm_mm_hole_node_start(hole);
hole_end = __drm_mm_hole_node_end(hole);
@@ -888,9 +884,17 @@ bool drm_mm_scan_remove_block(struct drm_mm_scan *scan,
DRM_MM_BUG_ON(!node->mm->scan_active);
node->mm->scan_active--;
 
+   /* During drm_mm_scan_add_block() we decoupled this node leaving
+* its pointers intact. Now that the caller is walking back along
+* the eviction list we can restore this block into its rightful
+* place on the full node_list. To confirm that the caller is walking
+* backwards correctly we check that prev_node->next == node->next,
+* i.e. both believe the same node should be on the other side of the
+* hole.
+*/
prev_node = list_prev_entry(node, node_list);
-
-   prev_node->hole_follows = node->scanned_preceeds_hole;
+   DRM_MM_BUG_ON(list_next_entry(prev_node, node_list) !=
+ list_next_entry(node, node_list));
list_add(>node_list, _node->node_list);
 
return (node->start + node->size > scan->hit_start &&
@@ -917,9 +921,6 @@ void drm_mm_init(struct drm_mm *mm, u64 start, u64 size)
INIT_LIST_HEAD(>head_node.node_list);
mm->head_node.allocated = 0;
mm->head_node.hole_follows = 1;
-   mm->head_node.scanned_block = 0;
-   mm->head_node.scanned_prev_free = 0;
-   mm->head_node.scanned_next_free = 0;
mm->head_node.mm = mm;
mm->head_node.start = start + size;
mm->head_node.size = start - mm->head_node.start;
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index 6ee87e1455bf..a1532eb0ffbc 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -74,11 +74,8 @@ struct drm_mm_node {
struct list_head hole_stack;
struct rb_node rb;
unsigned hole_follows : 1;
-   unsigned scanned_block : 1;
-   unsigned scanned_prev_free : 1;
-   unsigned scanned_next_free : 1;
-   unsigned scanned_preceeds_hole : 1;
unsigned allocated : 1;
+   bool scanned_block : 1;
unsigned long color;
u64 start;
u64 size;
@@ -118,8 +115,6 @@ struct drm_mm_scan {
u64 hit_start;
u64 hit_end;
 
-   struct drm_mm_node *prev_scanned_node;
-
unsigned long color;
unsigned int flags;
 };
-- 
2.11.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 04/40] drm: Constify the drm_mm API

2016-12-15 Thread Chris Wilson
Mark up the pointers as constant through the API where appropriate.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/drm_mm.c| 24 
 drivers/gpu/drm/i915/i915_gem_gtt.c |  2 +-
 include/drm/drm_mm.h| 27 +--
 3 files changed, 26 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 6e0735539545..7573661302a4 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -174,9 +174,9 @@ INTERVAL_TREE_DEFINE(struct drm_mm_node, rb,
 START, LAST, static inline, drm_mm_interval_tree)
 
 struct drm_mm_node *
-__drm_mm_interval_first(struct drm_mm *mm, u64 start, u64 last)
+__drm_mm_interval_first(const struct drm_mm *mm, u64 start, u64 last)
 {
-   return drm_mm_interval_tree_iter_first(>interval_tree,
+   return drm_mm_interval_tree_iter_first((struct rb_root 
*)>interval_tree,
   start, last);
 }
 EXPORT_SYMBOL(__drm_mm_interval_first);
@@ -881,9 +881,9 @@ EXPORT_SYMBOL(drm_mm_scan_remove_block);
  * True if the allocator is completely free, false if there's still a node
  * allocated in it.
  */
-bool drm_mm_clean(struct drm_mm * mm)
+bool drm_mm_clean(const struct drm_mm *mm)
 {
-   struct list_head *head = __drm_mm_nodes(mm);
+   const struct list_head *head = __drm_mm_nodes(mm);
 
return (head->next->next == head);
 }
@@ -897,7 +897,7 @@ EXPORT_SYMBOL(drm_mm_clean);
  *
  * Note that @mm must be cleared to 0 before calling this function.
  */
-void drm_mm_init(struct drm_mm * mm, u64 start, u64 size)
+void drm_mm_init(struct drm_mm *mm, u64 start, u64 size)
 {
INIT_LIST_HEAD(>hole_stack);
mm->scanned_blocks = 0;
@@ -936,8 +936,8 @@ void drm_mm_takedown(struct drm_mm *mm)
 }
 EXPORT_SYMBOL(drm_mm_takedown);
 
-static u64 drm_mm_debug_hole(struct drm_mm_node *entry,
-const char *prefix)
+static u64 drm_mm_debug_hole(const struct drm_mm_node *entry,
+const char *prefix)
 {
u64 hole_start, hole_end, hole_size;
 
@@ -958,9 +958,9 @@ static u64 drm_mm_debug_hole(struct drm_mm_node *entry,
  * @mm: drm_mm allocator to dump
  * @prefix: prefix to use for dumping to dmesg
  */
-void drm_mm_debug_table(struct drm_mm *mm, const char *prefix)
+void drm_mm_debug_table(const struct drm_mm *mm, const char *prefix)
 {
-   struct drm_mm_node *entry;
+   const struct drm_mm_node *entry;
u64 total_used = 0, total_free = 0, total = 0;
 
total_free += drm_mm_debug_hole(>head_node, prefix);
@@ -979,7 +979,7 @@ void drm_mm_debug_table(struct drm_mm *mm, const char 
*prefix)
 EXPORT_SYMBOL(drm_mm_debug_table);
 
 #if defined(CONFIG_DEBUG_FS)
-static u64 drm_mm_dump_hole(struct seq_file *m, struct drm_mm_node *entry)
+static u64 drm_mm_dump_hole(struct seq_file *m, const struct drm_mm_node 
*entry)
 {
u64 hole_start, hole_end, hole_size;
 
@@ -1000,9 +1000,9 @@ static u64 drm_mm_dump_hole(struct seq_file *m, struct 
drm_mm_node *entry)
  * @m: seq_file to dump to
  * @mm: drm_mm allocator to dump
  */
-int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm)
+int drm_mm_dump_table(struct seq_file *m, const struct drm_mm *mm)
 {
-   struct drm_mm_node *entry;
+   const struct drm_mm_node *entry;
u64 total_used = 0, total_free = 0, total = 0;
 
total_free += drm_mm_dump_hole(m, >head_node);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 4d82f38a000b..97fd66e4e3d0 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2699,7 +2699,7 @@ void i915_gem_gtt_finish_pages(struct drm_i915_gem_object 
*obj,
dma_unmap_sg(kdev, pages->sgl, pages->nents, PCI_DMA_BIDIRECTIONAL);
 }
 
-static void i915_gtt_color_adjust(struct drm_mm_node *node,
+static void i915_gtt_color_adjust(const struct drm_mm_node *node,
  unsigned long color,
  u64 *start,
  u64 *end)
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index 0cc1b78c9ec2..5c7f15875b6a 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -102,7 +102,8 @@ struct drm_mm {
u64 scan_end;
struct drm_mm_node *prev_scanned_node;
 
-   void (*color_adjust)(struct drm_mm_node *node, unsigned long color,
+   void (*color_adjust)(const struct drm_mm_node *node,
+unsigned long color,
 u64 *start, u64 *end);
 };
 
@@ -116,7 +117,7 @@ struct drm_mm {
  * Returns:
  * True if the @node is allocated.
  */
-static inline bool drm_mm_node_allocated(struct drm_mm_node *node)
+static inline bool drm_mm_node_allocated(const struct drm_mm_node *node)
 {
return node->allocated;
 }
@@ -131,12 +132,12 @@ static inline bool 

[Intel-gfx] [PATCH v2 19/40] drm: kselftest for drm_mm and color adjustment

2016-12-15 Thread Chris Wilson
Check that after applying the driver's color adjustment, fitting of the
node and its alignment are still correct.

v2: s/no_color_touching/separate_adjacent_colors/

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/selftests/drm_mm_selftests.h |   1 +
 drivers/gpu/drm/selftests/test-drm_mm.c  | 185 +++
 2 files changed, 186 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index cd508e3d6538..ff44f39a1826 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -18,3 +18,4 @@ selftest(align64, igt_align64)
 selftest(evict, igt_evict)
 selftest(evict_range, igt_evict_range)
 selftest(topdown, igt_topdown)
+selftest(color, igt_color)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index fc76d787cfd4..6b3af04eb582 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -1645,6 +1645,191 @@ static int igt_topdown(void *ignored)
return ret;
 }
 
+static void separate_adjacent_colors(const struct drm_mm_node *node,
+unsigned long color,
+u64 *start,
+u64 *end)
+{
+   if (node->allocated && node->color != color)
+   ++*start;
+
+   node = list_next_entry(node, node_list);
+   if (node->allocated && node->color != color)
+   --*end;
+}
+
+static bool colors_abutt(const struct drm_mm_node *node)
+{
+   if (!node->hole_follows &&
+   list_next_entry(node, node_list)->allocated) {
+   pr_err("colors abutt; %ld [%llx + %llx] is next to %ld [%llx + 
%llx]!\n",
+  node->color, node->start, node->size,
+  list_next_entry(node, node_list)->color,
+  list_next_entry(node, node_list)->start,
+  list_next_entry(node, node_list)->size);
+   return true;
+   }
+
+   return false;
+}
+
+static int igt_color(void *ignored)
+{
+   const unsigned int count = min(4096u, max_iterations);
+   const struct insert_mode *mode;
+   struct drm_mm mm;
+   struct drm_mm_node *node, *nn;
+   unsigned int n;
+   int ret = -EINVAL, err;
+
+   /* Color adjustment complicates everything. First we just check
+* that when we insert a node we apply any color_adjustment callback.
+* The callback we use should ensure that there is a gap between
+* any two nodes, and so after each insertion we check that those
+* holes are inserted and that they are preserved.
+*/
+
+   drm_mm_init(, 0, U64_MAX);
+
+   for (n = 1; n <= count; n++) {
+   node = kzalloc(sizeof(*node), GFP_KERNEL);
+   if (!node) {
+   ret = -ENOMEM;
+   goto out;
+   }
+
+   err = drm_mm_insert_node_generic(, node, n, 0, n,
+DRM_MM_SEARCH_DEFAULT,
+DRM_MM_CREATE_DEFAULT);
+   if (err || !assert_node(node, , n, 0, n)) {
+   pr_err("insert failed, step %d\n", n);
+   kfree(node);
+   ret = err ?: -EINVAL;
+   goto out;
+   }
+   }
+
+   drm_mm_for_each_node_safe(node, nn, ) {
+   if (node->color != node->size) {
+   pr_err("invalid color stored: expected %lld, found 
%ld\n",
+  node->size, node->color);
+
+   goto out;
+   }
+
+   drm_mm_remove_node(node);
+   kfree(node);
+   }
+
+   /* Now, let's start experimenting with applying a color callback */
+   mm.color_adjust = separate_adjacent_colors;
+   for (mode = insert_modes; mode->name; mode++) {
+   u64 last;
+
+   node = kzalloc(sizeof(*node), GFP_KERNEL);
+   if (!node) {
+   ret = -ENOMEM;
+   goto out;
+   }
+
+   node->size = 1 + 2*count;
+   node->color = node->size;
+
+   err = drm_mm_reserve_node(, node);
+   if (err) {
+   pr_err("initial reserve failed!\n");
+   goto out;
+   }
+
+   last = node->start + node->size;
+
+   for (n = 1; n <= count; n++) {
+   int rem;
+
+   node = kzalloc(sizeof(*node), GFP_KERNEL);
+   if (!node) {
+   ret = -ENOMEM;
+   goto out;
+   }
+
+

Re: [Intel-gfx] ??? Fi.CI.BAT: failure for drm/i915: relax uncritical udelay_range() settings

2016-12-15 Thread Nicholas Mc Guire
On Fri, Dec 16, 2016 at 07:29:59AM +, Saarinen, Jani wrote:
> > == Series Details ==
> > 
> > Series: drm/i915: relax uncritical udelay_range() settings
> > URL   : https://patchwork.freedesktop.org/series/16900/
> > State : failure
> > 
> > == Summary ==
> > 
> > Series 16900v1 drm/i915: relax uncritical udelay_range() settings
> > https://patchwork.freedesktop.org/api/1.0/series/16900/revisions/1/mbox/
> > 
> > Test gem_ringfill:
> > Subgroup basic-default-hang:
> > pass   -> INCOMPLETE (fi-hsw-4770)
> running: igt/gem_ringfill/basic-default-hang
> [117/247] skip: 8, pass: 109 /  
> Build timed out (after 17 minutes). Marking the build as aborted.
>
This might be a conflict caused by the initial patch which was discssed
and then after agreeing that rather than moving to udelay() usleep:range
with som adjustments would be the right way to go. 
are both patches queued now ?

I think I caused the problem by changing the subject line of the patch 
while adding a V2 - because the original subject line was no longer corrct
(it noted udely) - the V2 patch is marked as "rev 1" in patchwork though.
 
not quite clear - anyway sorry if I made some sort of a mess here
the patch applies cleanly on next-20161216.

thx!
hofrat
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 26/40] drm: Simplify drm_mm_clean()

2016-12-15 Thread Chris Wilson
Since commit ea7b1dd44867 ("drm: mm: track free areas implicitly"),
to test whether there are any nodes allocated within the range manager,
we merely have to ask whether the node_list is empty.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c | 19 +--
 include/drm/drm_mm.h | 14 +-
 2 files changed, 14 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 6450690f5578..14a5ef505f1b 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -873,22 +873,6 @@ bool drm_mm_scan_remove_block(struct drm_mm_node *node)
 EXPORT_SYMBOL(drm_mm_scan_remove_block);
 
 /**
- * drm_mm_clean - checks whether an allocator is clean
- * @mm: drm_mm allocator to check
- *
- * Returns:
- * True if the allocator is completely free, false if there's still a node
- * allocated in it.
- */
-bool drm_mm_clean(const struct drm_mm *mm)
-{
-   const struct list_head *head = __drm_mm_nodes(mm);
-
-   return (head->next->next == head);
-}
-EXPORT_SYMBOL(drm_mm_clean);
-
-/**
  * drm_mm_init - initialize a drm-mm allocator
  * @mm: the drm_mm structure to initialize
  * @start: start of the range managed by @mm
@@ -928,10 +912,9 @@ EXPORT_SYMBOL(drm_mm_init);
  */
 void drm_mm_takedown(struct drm_mm *mm)
 {
-   if (WARN(!list_empty(__drm_mm_nodes(mm)),
+   if (WARN(!drm_mm_clean(mm),
 "Memory manager not clean during takedown.\n"))
show_leaks(mm);
-
 }
 EXPORT_SYMBOL(drm_mm_takedown);
 
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index 47ca6502ef29..2f28a806d015 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -330,7 +330,19 @@ void drm_mm_remove_node(struct drm_mm_node *node);
 void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new);
 void drm_mm_init(struct drm_mm *mm, u64 start, u64 size);
 void drm_mm_takedown(struct drm_mm *mm);
-bool drm_mm_clean(const struct drm_mm *mm);
+
+/**
+ * drm_mm_clean - checks whether an allocator is clean
+ * @mm: drm_mm allocator to check
+ *
+ * Returns:
+ * True if the allocator is completely free, false if there's still a node
+ * allocated in it.
+ */
+static inline bool drm_mm_clean(const struct drm_mm *mm)
+{
+   return list_empty(__drm_mm_nodes(mm));
+}
 
 struct drm_mm_node *
 __drm_mm_interval_first(const struct drm_mm *mm, u64 start, u64 last);
-- 
2.11.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 27/40] drm: Add asserts to catch overflow in drm_mm_init() and drm_mm_init_scan()

2016-12-15 Thread Chris Wilson
A simple assert to ensure that we don't overflow start + size when
initialising the drm_mm, or its scanner.

In future, we may want to switch to tracking the value of ranges (rather
than size) so that we can cover the full u64, for example like resource
tracking.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/drm_mm.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 14a5ef505f1b..57267845b7d4 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -729,6 +729,8 @@ void drm_mm_init_scan(struct drm_mm *mm,
  u64 alignment,
  unsigned long color)
 {
+   DRM_MM_BUG_ON(size == 0);
+
mm->scan_color = color;
mm->scan_alignment = alignment;
mm->scan_size = size;
@@ -764,6 +766,9 @@ void drm_mm_init_scan_with_range(struct drm_mm *mm,
 u64 start,
 u64 end)
 {
+   DRM_MM_BUG_ON(start >= end);
+   DRM_MM_BUG_ON(size == 0 || size > end - start);
+
mm->scan_color = color;
mm->scan_alignment = alignment;
mm->scan_size = size;
@@ -882,6 +887,8 @@ EXPORT_SYMBOL(drm_mm_scan_remove_block);
  */
 void drm_mm_init(struct drm_mm *mm, u64 start, u64 size)
 {
+   DRM_MM_BUG_ON(start + size <= start);
+
INIT_LIST_HEAD(>hole_stack);
mm->scanned_blocks = 0;
 
-- 
2.11.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 18/40] drm: kselftest for drm_mm and top-down allocation

2016-12-15 Thread Chris Wilson
Check that if we request top-down allocation from drm_mm_insert_node()
we receive the next available hole from the top.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/selftests/drm_mm_selftests.h |   1 +
 drivers/gpu/drm/selftests/test-drm_mm.c  | 123 +++
 2 files changed, 124 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index 965aca65c160..cd508e3d6538 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -17,3 +17,4 @@ selftest(align32, igt_align32)
 selftest(align64, igt_align64)
 selftest(evict, igt_evict)
 selftest(evict_range, igt_evict_range)
+selftest(topdown, igt_topdown)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index 6c4679304358..fc76d787cfd4 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -1522,6 +1522,129 @@ static int igt_evict_range(void *ignored)
return ret;
 }
 
+static unsigned int node_index(const struct drm_mm_node *node)
+{
+   return div64_u64(node->start, node->size);
+}
+
+static int igt_topdown(void *ignored)
+{
+   RND_STATE(prng, random_seed);
+   const unsigned int count = 8192;
+   unsigned int size;
+   unsigned long *bitmap = NULL;
+   struct drm_mm mm;
+   struct drm_mm_node *nodes, *node, *next;
+   unsigned int *order, n, m, o = 0;
+   int ret, err;
+
+   /* When allocating top-down, we expect to be returned a node
+* from a suitable hole at the top of the drm_mm. We check that
+* the returned node does match the highest available slot.
+*/
+
+   ret = -ENOMEM;
+   nodes = vzalloc(count * sizeof(*nodes));
+   if (!nodes)
+   goto err;
+
+   bitmap = kzalloc(count / BITS_PER_LONG * sizeof(unsigned long),
+GFP_TEMPORARY);
+   if (!bitmap)
+   goto err_nodes;
+
+   order = drm_random_order(count, );
+   if (!order)
+   goto err_bitmap;
+
+   ret = -EINVAL;
+   for (size = 1; size <= 64; size <<= 1) {
+   drm_mm_init(, 0, size*count);
+   for (n = 0; n < count; n++) {
+   err = drm_mm_insert_node_generic(,
+[n], size, 0, n,
+DRM_MM_SEARCH_BELOW,
+DRM_MM_CREATE_TOP);
+   if (err || !assert_node([n], , size, 0, n)) {
+   pr_err("insert failed, size %u step %d\n", 
size, n);
+   ret = err ?: -EINVAL;
+   goto out;
+   }
+
+   if (nodes[n].hole_follows) {
+   pr_err("hole after topdown insert %d, 
start=%llx\n, size=%u",
+  n, nodes[n].start, size);
+   goto out;
+   }
+
+   if (!assert_one_hole(, 0, size*(count - n - 1)))
+   goto out;
+   }
+
+   if (!assert_continuous(, size))
+   goto out;
+
+   drm_random_reorder(order, count, );
+   drm_for_each_prime(n, min(count, max_prime)) {
+   for (m = 0; m < n; m++) {
+   node = [order[(o + m) % count]];
+   drm_mm_remove_node(node);
+   __set_bit(node_index(node), bitmap);
+   }
+
+   for (m = 0; m < n; m++) {
+   unsigned int last;
+
+   node = [order[(o + m) % count]];
+   err = drm_mm_insert_node_generic(, node, 
size, 0, 0,
+
DRM_MM_SEARCH_BELOW,
+
DRM_MM_CREATE_TOP);
+   if (err || !assert_node(node, , size, 0, 0)) 
{
+   pr_err("insert failed, step %d/%d\n", 
m, n);
+   ret = err ?: -EINVAL;
+   goto out;
+   }
+
+   if (node->hole_follows) {
+   pr_err("hole after topdown insert 
%d/%d, start=%llx\n",
+  m, n, node->start);
+   goto out;
+   }
+
+   last = find_last_bit(bitmap, count);
+   if 

[Intel-gfx] [PATCH v2 31/40] drm: Fix application of color vs range restriction when scanning drm_mm

2016-12-15 Thread Chris Wilson
The range restriction should be applied after the color adjustment, or
else we may inadvertently apply the color adjustment to the restricted
hole (and not against its neighbours).

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 04b1d36c4ebc..956782e7b092 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -772,6 +772,7 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
struct drm_mm *mm = scan->mm;
struct drm_mm_node *hole;
u64 hole_start, hole_end;
+   u64 col_start, col_end;
u64 adj_start, adj_end;
 
DRM_MM_BUG_ON(node->mm != mm);
@@ -789,14 +790,16 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
node->node_list.next = >prev_scanned_node->node_list;
scan->prev_scanned_node = node;
 
-   hole_start = drm_mm_hole_node_start(hole);
-   hole_end = drm_mm_hole_node_end(hole);
-
-   adj_start = max(hole_start, scan->range_start);
-   adj_end = min(hole_end, scan->range_end);
+   hole_start = __drm_mm_hole_node_start(hole);
+   hole_end = __drm_mm_hole_node_end(hole);
 
+   col_start = hole_start;
+   col_end = hole_end;
if (mm->color_adjust)
-   mm->color_adjust(hole, scan->color, _start, _end);
+   mm->color_adjust(hole, scan->color, _start, _end);
+
+   adj_start = max(col_start, scan->range_start);
+   adj_end = min(col_end, scan->range_end);
 
if (check_free_hole(adj_start, adj_end,
scan->size, scan->alignment)) {
-- 
2.11.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 24/40] drm: Fix kerneldoc for drm_mm_scan_remove_block()

2016-12-15 Thread Chris Wilson
The nodes must be removed in the *reverse* order. This is correct in the
overview, but backwards in the function description. Whilst here add
Intel's copyright statement and tweak some formatting.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/drm_mm.c | 34 ++
 include/drm/drm_mm.h | 19 +--
 2 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 2d02ab0925a9..ead164093ac7 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -1,6 +1,7 @@
 /**
  *
  * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA.
+ * Copyright 2016 Intel Corporation
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -31,9 +32,9 @@
  * class implementation for more advanced memory managers.
  *
  * Note that the algorithm used is quite simple and there might be substantial
- * performance gains if a smarter free list is implemented. Currently it is 
just an
- * unordered stack of free regions. This could easily be improved if an RB-tree
- * is used instead. At least if we expect heavy fragmentation.
+ * performance gains if a smarter free list is implemented. Currently it is
+ * just an unordered stack of free regions. This could easily be improved if
+ * an RB-tree is used instead. At least if we expect heavy fragmentation.
  *
  * Aligned allocations can also see improvement.
  *
@@ -67,7 +68,7 @@
  * where an object needs to be created which exactly matches the firmware's
  * scanout target. As long as the range is still free it can be inserted 
anytime
  * after the allocator is initialized, which helps with avoiding looped
- * depencies in the driver load sequence.
+ * dependencies in the driver load sequence.
  *
  * drm_mm maintains a stack of most recently freed holes, which of all
  * simplistic datastructures seems to be a fairly decent approach to clustering
@@ -78,14 +79,14 @@
  *
  * drm_mm supports a few features: Alignment and range restrictions can be
  * supplied. Further more every _mm_node has a color value (which is just 
an
- * opaqua unsigned long) which in conjunction with a driver callback can be 
used
+ * opaque unsigned long) which in conjunction with a driver callback can be 
used
  * to implement sophisticated placement restrictions. The i915 DRM driver uses
  * this to implement guard pages between incompatible caching domains in the
  * graphics TT.
  *
- * Two behaviors are supported for searching and allocating: bottom-up and 
top-down.
- * The default is bottom-up. Top-down allocation can be used if the memory area
- * has different restrictions, or just to reduce fragmentation.
+ * Two behaviors are supported for searching and allocating: bottom-up and
+ * top-down. The default is bottom-up. Top-down allocation can be used if the
+ * memory area has different restrictions, or just to reduce fragmentation.
  *
  * Finally iteration helpers to walk all nodes and all holes are provided as 
are
  * some basic allocator dumpers for debugging.
@@ -510,7 +511,7 @@ EXPORT_SYMBOL(drm_mm_insert_node_in_range_generic);
  *
  * This just removes a node from its drm_mm allocator. The node does not need 
to
  * be cleared again before it can be re-inserted into this or any other drm_mm
- * allocator. It is a bug to call this function on a un-allocated node.
+ * allocator. It is a bug to call this function on a unallocated node.
  */
 void drm_mm_remove_node(struct drm_mm_node *node)
 {
@@ -689,16 +690,16 @@ EXPORT_SYMBOL(drm_mm_replace_node);
  * efficient when we simply start to select all objects from the tail of an LRU
  * until there's a suitable hole: Especially for big objects or nodes that
  * otherwise have special allocation constraints there's a good chance we evict
- * lots of (smaller) objects unecessarily.
+ * lots of (smaller) objects unnecessarily.
  *
  * The DRM range allocator supports this use-case through the scanning
  * interfaces. First a scan operation needs to be initialized with
- * drm_mm_init_scan() or drm_mm_init_scan_with_range(). The the driver adds
+ * drm_mm_init_scan() or drm_mm_init_scan_with_range(). The driver adds
  * objects to the roaster (probably by walking an LRU list, but this can be
  * freely implemented) until a suitable hole is found or there's no further
- * evitable object.
+ * evictable object.
  *
- * The the driver must walk through all objects again in exactly the reverse
+ * The driver must walk through all objects again in exactly the reverse
  * order to restore the allocator state. Note that while the allocator is used
  * in the scan mode no other operation is allowed.
  *
@@ -838,9 +839,10 @@ EXPORT_SYMBOL(drm_mm_scan_add_block);
  * drm_mm_scan_remove_block - remove a node from the scan list
  * @node: drm_mm_node to remove
  *
- * Nodes _must_ be removed 

[Intel-gfx] [PATCH v2 25/40] drm: Detect overflow in drm_mm_reserve_node()

2016-12-15 Thread Chris Wilson
Protect ourselves from a caller passing in node.start + node.size that
will overflow and trick us into reserving that node.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/drm_mm.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index ead164093ac7..6450690f5578 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -308,10 +308,9 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct 
drm_mm_node *node)
u64 hole_start, hole_end;
u64 adj_start, adj_end;
 
-   if (WARN_ON(node->size == 0))
-   return -EINVAL;
-
end = node->start + node->size;
+   if (unlikely(end <= node->start))
+   return -ENOSPC;
 
/* Find the relevant hole to add our node to */
hole = drm_mm_interval_tree_iter_first(>interval_tree,
-- 
2.11.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 29/40] drm: Rename prev_node to hole in drm_mm_scan_add_block()

2016-12-15 Thread Chris Wilson
Acknowledging that we were building up the hole was more useful to me
when reading the code, than knowing the relationship between this node
and the previous node.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/drm_mm.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 0f1396b0d39a..6bb61f2212f8 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -811,7 +811,7 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
   struct drm_mm_node *node)
 {
struct drm_mm *mm = scan->mm;
-   struct drm_mm_node *prev_node;
+   struct drm_mm_node *hole;
u64 hole_start, hole_end;
u64 adj_start, adj_end;
 
@@ -821,17 +821,17 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
node->scanned_block = 1;
mm->scan_active++;
 
-   prev_node = list_prev_entry(node, node_list);
+   hole = list_prev_entry(node, node_list);
 
-   node->scanned_preceeds_hole = prev_node->hole_follows;
-   prev_node->hole_follows = 1;
+   node->scanned_preceeds_hole = hole->hole_follows;
+   hole->hole_follows = 1;
list_del(>node_list);
-   node->node_list.prev = _node->node_list;
+   node->node_list.prev = >node_list;
node->node_list.next = >prev_scanned_node->node_list;
scan->prev_scanned_node = node;
 
-   adj_start = hole_start = drm_mm_hole_node_start(prev_node);
-   adj_end = hole_end = drm_mm_hole_node_end(prev_node);
+   adj_start = hole_start = drm_mm_hole_node_start(hole);
+   adj_end = hole_end = drm_mm_hole_node_end(hole);
 
if (scan->check_range) {
if (adj_start < scan->range_start)
@@ -841,7 +841,7 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
}
 
if (mm->color_adjust)
-   mm->color_adjust(prev_node, scan->color, _start, _end);
+   mm->color_adjust(hole, scan->color, _start, _end);
 
if (check_free_hole(adj_start, adj_end,
scan->size, scan->alignment)) {
-- 
2.11.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 05/40] drm: Compile time enabling for asserts in drm_mm

2016-12-15 Thread Chris Wilson
Use CONFIG_DRM_DEBUG_MM to conditionally enable the internal and
validation checking using BUG_ON. Ideally these paths should all be
exercised by CI selftests (with the asserts enabled).

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c | 45 +++--
 include/drm/drm_mm.h |  8 +++-
 2 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 7573661302a4..2b76167ef39f 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -237,7 +237,7 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
u64 adj_start = hole_start;
u64 adj_end = hole_end;
 
-   BUG_ON(node->allocated);
+   DRM_MM_BUG_ON(node->allocated);
 
if (mm->color_adjust)
mm->color_adjust(hole_node, color, _start, _end);
@@ -258,8 +258,8 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
}
}
 
-   BUG_ON(adj_start < hole_start);
-   BUG_ON(adj_end > hole_end);
+   DRM_MM_BUG_ON(adj_start < hole_start);
+   DRM_MM_BUG_ON(adj_end > hole_end);
 
if (adj_start == hole_start) {
hole_node->hole_follows = 0;
@@ -276,7 +276,7 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
 
drm_mm_interval_tree_add_node(hole_node, node);
 
-   BUG_ON(node->start + node->size > adj_end);
+   DRM_MM_BUG_ON(node->start + node->size > adj_end);
 
node->hole_follows = 0;
if (__drm_mm_hole_node_start(node) < hole_end) {
@@ -409,7 +409,7 @@ static void drm_mm_insert_helper_range(struct drm_mm_node 
*hole_node,
u64 adj_start = hole_start;
u64 adj_end = hole_end;
 
-   BUG_ON(!hole_node->hole_follows || node->allocated);
+   DRM_MM_BUG_ON(!hole_node->hole_follows || node->allocated);
 
if (adj_start < start)
adj_start = start;
@@ -450,10 +450,10 @@ static void drm_mm_insert_helper_range(struct drm_mm_node 
*hole_node,
 
drm_mm_interval_tree_add_node(hole_node, node);
 
-   BUG_ON(node->start < start);
-   BUG_ON(node->start < adj_start);
-   BUG_ON(node->start + node->size > adj_end);
-   BUG_ON(node->start + node->size > end);
+   DRM_MM_BUG_ON(node->start < start);
+   DRM_MM_BUG_ON(node->start < adj_start);
+   DRM_MM_BUG_ON(node->start + node->size > adj_end);
+   DRM_MM_BUG_ON(node->start + node->size > end);
 
node->hole_follows = 0;
if (__drm_mm_hole_node_start(node) < hole_end) {
@@ -519,22 +519,21 @@ void drm_mm_remove_node(struct drm_mm_node *node)
struct drm_mm *mm = node->mm;
struct drm_mm_node *prev_node;
 
-   if (WARN_ON(!node->allocated))
-   return;
-
-   BUG_ON(node->scanned_block || node->scanned_prev_free
-  || node->scanned_next_free);
+   DRM_MM_BUG_ON(!node->allocated);
+   DRM_MM_BUG_ON(node->scanned_block ||
+ node->scanned_prev_free ||
+ node->scanned_next_free);
 
prev_node =
list_entry(node->node_list.prev, struct drm_mm_node, node_list);
 
if (node->hole_follows) {
-   BUG_ON(__drm_mm_hole_node_start(node) ==
-  __drm_mm_hole_node_end(node));
+   DRM_MM_BUG_ON(__drm_mm_hole_node_start(node) ==
+ __drm_mm_hole_node_end(node));
list_del(>hole_stack);
} else
-   BUG_ON(__drm_mm_hole_node_start(node) !=
-  __drm_mm_hole_node_end(node));
+   DRM_MM_BUG_ON(__drm_mm_hole_node_start(node) !=
+ __drm_mm_hole_node_end(node));
 
 
if (!prev_node->hole_follows) {
@@ -578,7 +577,7 @@ static struct drm_mm_node *drm_mm_search_free_generic(const 
struct drm_mm *mm,
u64 adj_end;
u64 best_size;
 
-   BUG_ON(mm->scanned_blocks);
+   DRM_MM_BUG_ON(mm->scanned_blocks);
 
best = NULL;
best_size = ~0UL;
@@ -622,7 +621,7 @@ static struct drm_mm_node 
*drm_mm_search_free_in_range_generic(const struct drm_
u64 adj_end;
u64 best_size;
 
-   BUG_ON(mm->scanned_blocks);
+   DRM_MM_BUG_ON(mm->scanned_blocks);
 
best = NULL;
best_size = ~0UL;
@@ -668,6 +667,8 @@ static struct drm_mm_node 
*drm_mm_search_free_in_range_generic(const struct drm_
  */
 void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new)
 {
+   DRM_MM_BUG_ON(!old->allocated);
+
list_replace(>node_list, >node_list);
list_replace(>hole_stack, >hole_stack);
rb_replace_node(>rb, >rb, >mm->interval_tree);
@@ -798,7 +799,7 @@ bool drm_mm_scan_add_block(struct drm_mm_node *node)
 
mm->scanned_blocks++;
 
-   BUG_ON(node->scanned_block);
+   

[Intel-gfx] [PATCH v2 16/40] drm: kselftest for drm_mm and eviction

2016-12-15 Thread Chris Wilson
Check that we add arbitrary blocks to the eviction scanner in order to
find the first minimal hole that matches our request.

v2: Refactor out some common eviction code for later

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/selftests/drm_mm_selftests.h |   1 +
 drivers/gpu/drm/selftests/test-drm_mm.c  | 337 +++
 2 files changed, 338 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index a7a3763f8b20..a31b4458c7eb 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -15,3 +15,4 @@ selftest(insert_range, igt_insert_range)
 selftest(align, igt_align)
 selftest(align32, igt_align32)
 selftest(align64, igt_align64)
+selftest(evict, igt_evict)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index dc3aee222158..4881752d6424 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -524,6 +524,10 @@ static const struct insert_mode {
{ "top-down", DRM_MM_SEARCH_BELOW, DRM_MM_CREATE_TOP },
{ "best", DRM_MM_SEARCH_BEST, DRM_MM_CREATE_DEFAULT },
{}
+}, evict_modes[] = {
+   { "default", DRM_MM_SEARCH_DEFAULT, DRM_MM_CREATE_DEFAULT },
+   { "top-down", DRM_MM_SEARCH_BELOW, DRM_MM_CREATE_TOP },
+   {}
 };
 
 static int __igt_insert(unsigned int count, u64 size, bool replace)
@@ -1080,6 +1084,339 @@ static int igt_align64(void *ignored)
return igt_align_pot(64);
 }
 
+static void show_scan(const struct drm_mm *scan)
+{
+   pr_info("scan: hit [%llx, %llx], size=%lld, align=%d, color=%ld\n",
+   scan->scan_hit_start, scan->scan_hit_end,
+   scan->scan_size, scan->scan_alignment, scan->scan_color);
+}
+
+static void show_holes(const struct drm_mm *mm, int count)
+{
+   u64 hole_start, hole_end;
+   struct drm_mm_node *hole;
+
+   drm_mm_for_each_hole(hole, mm, hole_start, hole_end) {
+   struct drm_mm_node *next = list_next_entry(hole, node_list);
+   const char *node1 = NULL, *node2 = NULL;
+
+   if (hole->allocated)
+   node1 = kasprintf(GFP_KERNEL,
+ "[%llx + %lld, color=%ld], ",
+ hole->start, hole->size, hole->color);
+
+   if (next->allocated)
+   node2 = kasprintf(GFP_KERNEL,
+ ", [%llx + %lld, color=%ld]",
+ next->start, next->size, next->color);
+
+   pr_info("%sHole [%llx - %llx, size %lld]%s\n",
+   node1,
+   hole_start, hole_end, hole_end - hole_start,
+   node2);
+
+   kfree(node2);
+   kfree(node1);
+
+   if (!--count)
+   break;
+   }
+}
+
+struct evict_node {
+   struct drm_mm_node node;
+   struct list_head link;
+};
+
+static bool evict_nodes(struct drm_mm *mm,
+   struct evict_node *nodes,
+   unsigned int *order,
+   unsigned int count,
+   struct list_head *evict_list)
+{
+   struct evict_node *e, *en;
+   unsigned int i;
+
+   for (i = 0; i < count; i++) {
+   e = [order ? order[i] : i];
+   list_add(>link, evict_list);
+   if (drm_mm_scan_add_block(>node))
+   break;
+   }
+   list_for_each_entry_safe(e, en, evict_list, link) {
+   if (!drm_mm_scan_remove_block(>node))
+   list_del(>link);
+   }
+   if (list_empty(evict_list)) {
+   pr_err("Failed to find eviction: size=%lld [avail=%d], align=%d 
(color=%lu)\n",
+  mm->scan_size, count,
+  mm->scan_alignment,
+  mm->scan_color);
+   return false;
+   }
+
+   list_for_each_entry(e, evict_list, link)
+   drm_mm_remove_node(>node);
+
+   return true;
+}
+
+static bool evict_nothing(struct drm_mm *mm,
+ unsigned int total_size,
+ struct evict_node *nodes)
+{
+   LIST_HEAD(evict_list);
+   struct evict_node *e;
+   struct drm_mm_node *node;
+   unsigned int n;
+
+   drm_mm_init_scan(mm, 1, 0, 0);
+   for (n = 0; n < total_size; n++) {
+   e = [n];
+   list_add(>link, _list);
+   drm_mm_scan_add_block(>node);
+   }
+   list_for_each_entry(e, _list, link)
+   drm_mm_scan_remove_block(>node);
+
+   for (n = 0; n < total_size; n++) {
+   e = [n];
+
+   if (!drm_mm_node_allocated(>node)) {
+

[Intel-gfx] [PATCH v2 12/40] drm: kselftest for drm_mm_insert_node()

2016-12-15 Thread Chris Wilson
Exercise drm_mm_insert_node(), check that we can't overfill a range and
that the lists are correct after reserving/removing.

v2: Extract helpers for the repeated tests
v3: Iterate over all allocation flags

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/selftests/drm_mm_selftests.h |   1 +
 drivers/gpu/drm/selftests/test-drm_mm.c  | 220 +++
 2 files changed, 221 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index 693d85677e7f..727c6d7255e0 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -9,3 +9,4 @@ selftest(sanitycheck, igt_sanitycheck) /* keep first (selfcheck 
for igt) */
 selftest(init, igt_init)
 selftest(debug, igt_debug)
 selftest(reserve, igt_reserve)
+selftest(insert, igt_insert)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index 2e40f94cb9d3..9621820a1cda 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -131,6 +131,48 @@ static bool assert_continuous(const struct drm_mm *mm, u64 
size)
return true;
 }
 
+static u64 misaligned(struct drm_mm_node *node, u64 alignment)
+{
+   u64 rem;
+
+   if (!alignment)
+   return 0;
+
+   div64_u64_rem(node->start, alignment, );
+   return rem;
+}
+
+static bool assert_node(struct drm_mm_node *node, struct drm_mm *mm,
+   u64 size, u64 alignment, unsigned long color)
+{
+   bool ok = true;
+
+   if (!drm_mm_node_allocated(node) || node->mm != mm) {
+   pr_err("node not allocated\n");
+   ok = false;
+   }
+
+   if (node->size != size) {
+   pr_err("node has wrong size, found %llu, expected %llu\n",
+  node->size, size);
+   ok = false;
+   }
+
+   if (misaligned(node, alignment)) {
+   pr_err("node is misalinged, start %llx rem %llu, expected 
alignment %llu\n",
+  node->start, misaligned(node, alignment), alignment);
+   ok = false;
+   }
+
+   if (node->color != color) {
+   pr_err("node has wrong color, found %lu, expected %lu\n",
+  node->color, color);
+   ok = false;
+   }
+
+   return ok;
+}
+
 static int igt_init(void *ignored)
 {
const unsigned int size = 4096;
@@ -452,6 +494,184 @@ static int igt_reserve(void *ignored)
return 0;
 }
 
+static bool expect_insert_fail(struct drm_mm *mm, u64 size)
+{
+   struct drm_mm_node tmp = {};
+   int err;
+
+   err = drm_mm_insert_node(mm, , size, 0, DRM_MM_SEARCH_DEFAULT);
+   if (err != -ENOSPC)  {
+   if (!err) {
+   pr_err("impossible insert succeeded, node %llu + 
%llu\n",
+  tmp.start, tmp.size);
+   drm_mm_remove_node();
+   } else {
+   pr_err("impossible insert failed with wrong error %d 
[expected %d], size %llu\n",
+  err, -ENOSPC, size);
+   }
+   return false;
+   }
+
+   return true;
+}
+
+static const struct insert_mode {
+   const char *name;
+   unsigned int search_flags;
+   unsigned int create_flags;
+} insert_modes[] = {
+   { "default", DRM_MM_SEARCH_DEFAULT, DRM_MM_CREATE_DEFAULT },
+   { "top-down", DRM_MM_SEARCH_BELOW, DRM_MM_CREATE_TOP },
+   { "best", DRM_MM_SEARCH_BEST, DRM_MM_CREATE_DEFAULT },
+   {}
+};
+
+static int __igt_insert(unsigned int count, u64 size)
+{
+   RND_STATE(prng, random_seed);
+   const struct insert_mode *mode;
+   struct drm_mm mm;
+   struct drm_mm_node *nodes, *node, *next;
+   unsigned int *order, n, m, o = 0;
+   int ret, err;
+
+   /* Fill a range with lots of nodes, check it doesn't fail too early */
+
+   DRM_MM_BUG_ON(!count);
+   DRM_MM_BUG_ON(!size);
+
+   ret = -ENOMEM;
+   nodes = vzalloc(count * sizeof(*nodes));
+   if (!nodes)
+   goto err;
+
+   order = drm_random_order(count, );
+   if (!order)
+   goto err_nodes;
+
+   ret = -EINVAL;
+   drm_mm_init(, 0, count * size);
+
+   for (mode = insert_modes; mode->name; mode++) {
+   for (n = 0; n < count; n++) {
+   node = [n];
+   err = drm_mm_insert_node_generic(, node, size, 0, n,
+mode->search_flags,
+mode->create_flags);
+   if (err || !assert_node(node, , size, 0, n)) {
+   pr_err("%s insert failed, size %llu step %d\n",
+  mode->name, size, n);
+   ret = err ?: 

[Intel-gfx] [PATCH v2 30/40] drm: Unconditionally do the range check in drm_mm_scan_add_block()

2016-12-15 Thread Chris Wilson
Doing the check is trivial (low cost in comparison to overall eviction)
and helps simplify the code.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c  | 53 +++
 drivers/gpu/drm/i915/i915_gem_evict.c | 10 ++-
 include/drm/drm_mm.h  | 33 ++
 3 files changed, 34 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 6bb61f2212f8..04b1d36c4ebc 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -710,46 +710,6 @@ EXPORT_SYMBOL(drm_mm_replace_node);
  */
 
 /**
- * drm_mm_scan_init - initialize lru scanning
- * @scan: scan state
- * @mm: drm_mm to scan
- * @size: size of the allocation
- * @alignment: alignment of the allocation
- * @color: opaque tag value to use for the allocation
- *
- * This simply sets up the scanning routines with the parameters for the 
desired
- * hole. Note that there's no need to specify allocation flags, since they only
- * change the place a node is allocated from within a suitable hole.
- *
- * Warning:
- * As long as the scan list is non-empty, no other operations than
- * adding/removing nodes to/from the scan list are allowed.
- */
-void drm_mm_scan_init(struct drm_mm_scan *scan,
- struct drm_mm *mm,
- u64 size,
- u64 alignment,
- unsigned long color)
-{
-   DRM_MM_BUG_ON(size == 0);
-   DRM_MM_BUG_ON(mm->scan_active);
-
-   scan->mm = mm;
-
-   scan->color = color;
-   scan->alignment = alignment;
-   scan->size = size;
-
-   scan->check_range = 0;
-
-   scan->hit_start = U64_MAX;
-   scan->hit_end = 0;
-
-   scan->prev_scanned_node = NULL;
-}
-EXPORT_SYMBOL(drm_mm_scan_init);
-
-/**
  * drm_mm_scan_init_with_range - initialize range-restricted lru scanning
  * @scan: scan state
  * @mm: drm_mm to scan
@@ -788,7 +748,6 @@ void drm_mm_scan_init_with_range(struct drm_mm_scan *scan,
DRM_MM_BUG_ON(end <= start);
scan->range_start = start;
scan->range_end = end;
-   scan->check_range = 1;
 
scan->hit_start = U64_MAX;
scan->hit_end = 0;
@@ -830,15 +789,11 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
node->node_list.next = >prev_scanned_node->node_list;
scan->prev_scanned_node = node;
 
-   adj_start = hole_start = drm_mm_hole_node_start(hole);
-   adj_end = hole_end = drm_mm_hole_node_end(hole);
+   hole_start = drm_mm_hole_node_start(hole);
+   hole_end = drm_mm_hole_node_end(hole);
 
-   if (scan->check_range) {
-   if (adj_start < scan->range_start)
-   adj_start = scan->range_start;
-   if (adj_end > scan->range_end)
-   adj_end = scan->range_end;
-   }
+   adj_start = max(hole_start, scan->range_start);
+   adj_end = min(hole_end, scan->range_end);
 
if (mm->color_adjust)
mm->color_adjust(hole, scan->color, _start, _end);
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c 
b/drivers/gpu/drm/i915/i915_gem_evict.c
index 6db0d73c0aa7..77ded288534b 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -126,13 +126,9 @@ i915_gem_evict_something(struct i915_address_space *vm,
 * On each list, the oldest objects lie at the HEAD with the freshest
 * object on the TAIL.
 */
-   if (start != 0 || end != vm->total) {
-   drm_mm_scan_init_with_range(, >mm, min_size,
-   alignment, cache_level,
-   start, end);
-   } else
-   drm_mm_scan_init(, >mm, min_size,
-alignment, cache_level);
+   drm_mm_scan_init_with_range(, >mm,
+   min_size, alignment, cache_level,
+   start, end);
 
/* Retire before we search the active list. Although we have
 * reasonable accuracy in our retirement lists, we may have
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index 4db57bef98e0..8539832fac0f 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -120,7 +120,6 @@ struct drm_mm_scan {
struct drm_mm_node *prev_scanned_node;
 
unsigned long color;
-   bool check_range : 1;
 };
 
 /**
@@ -375,11 +374,6 @@ __drm_mm_interval_first(const struct drm_mm *mm, u64 
start, u64 last);
 node__ && node__->start < (end__); \
 node__ = list_next_entry(node__, node_list))
 
-void drm_mm_scan_init(struct drm_mm_scan *scan,
- struct drm_mm *mm,
- u64 size,
- u64 alignment,
- unsigned long color);
 void 

[Intel-gfx] [PATCH v2 02/40] drm/i915: Simplify i915_gtt_color_adjust()

2016-12-15 Thread Chris Wilson
If we remember that node_list is a circular list containing the fake
head_node, we can use a simple list_next_entry() and skip the NULL check
for the allocated check against the head_node.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 4543d7fa7fc2..4d82f38a000b 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2707,10 +2707,8 @@ static void i915_gtt_color_adjust(struct drm_mm_node 
*node,
if (node->color != color)
*start += 4096;
 
-   node = list_first_entry_or_null(>node_list,
-   struct drm_mm_node,
-   node_list);
-   if (node && node->allocated && node->color != color)
+   node = list_next_entry(node, node_list);
+   if (node->allocated && node->color != color)
*end -= 4096;
 }
 
-- 
2.11.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 01/40] drm/i915: Use the MRU stack search after evicting

2016-12-15 Thread Chris Wilson
When we evict from the GTT to make room for an object, the hole we
create is put onto the MRU stack inside the drm_mm range manager. On the
next search pass, we can speed up a PIN_HIGH allocation by referencing
that stack for the new hole.

v2: Pull together the 3 identical implements (ahem, a couple were
outdated) into a common routine for allocating a node and evicting as
necessary.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen  #v1
---
 drivers/gpu/drm/i915/gvt/aperture_gm.c | 33 +---
 drivers/gpu/drm/i915/i915_gem_gtt.c| 72 --
 drivers/gpu/drm/i915/i915_gem_gtt.h|  5 +++
 drivers/gpu/drm/i915/i915_vma.c| 40 ++-
 4 files changed, 70 insertions(+), 80 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/aperture_gm.c 
b/drivers/gpu/drm/i915/gvt/aperture_gm.c
index 7d33b607bc89..1bb7a5b80d47 100644
--- a/drivers/gpu/drm/i915/gvt/aperture_gm.c
+++ b/drivers/gpu/drm/i915/gvt/aperture_gm.c
@@ -48,47 +48,34 @@ static int alloc_gm(struct intel_vgpu *vgpu, bool high_gm)
 {
struct intel_gvt *gvt = vgpu->gvt;
struct drm_i915_private *dev_priv = gvt->dev_priv;
-   u32 alloc_flag, search_flag;
+   unsigned int flags;
u64 start, end, size;
struct drm_mm_node *node;
-   int retried = 0;
int ret;
 
if (high_gm) {
-   search_flag = DRM_MM_SEARCH_BELOW;
-   alloc_flag = DRM_MM_CREATE_TOP;
node = >gm.high_gm_node;
size = vgpu_hidden_sz(vgpu);
start = gvt_hidden_gmadr_base(gvt);
end = gvt_hidden_gmadr_end(gvt);
+   flags = PIN_HIGH;
} else {
-   search_flag = DRM_MM_SEARCH_DEFAULT;
-   alloc_flag = DRM_MM_CREATE_DEFAULT;
node = >gm.low_gm_node;
size = vgpu_aperture_sz(vgpu);
start = gvt_aperture_gmadr_base(gvt);
end = gvt_aperture_gmadr_end(gvt);
+   flags = PIN_MAPPABLE;
}
 
mutex_lock(_priv->drm.struct_mutex);
-search_again:
-   ret = drm_mm_insert_node_in_range_generic(_priv->ggtt.base.mm,
- node, size, 4096,
- I915_COLOR_UNEVICTABLE,
- start, end, search_flag,
- alloc_flag);
-   if (ret) {
-   ret = i915_gem_evict_something(_priv->ggtt.base,
-  size, 4096,
-  I915_COLOR_UNEVICTABLE,
-  start, end, 0);
-   if (ret == 0 && ++retried < 3)
-   goto search_again;
-
-   gvt_err("fail to alloc %s gm space from host, retried %d\n",
-   high_gm ? "high" : "low", retried);
-   }
+   ret = i915_gem_gtt_insert(_priv->ggtt.base, node,
+ size, 4096, I915_COLOR_UNEVICTABLE,
+ start, end, flags);
mutex_unlock(_priv->drm.struct_mutex);
+   if (ret)
+   gvt_err("fail to alloc %s gm space from host\n",
+   high_gm ? "high" : "low");
+
return ret;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index ef00d36680c9..4543d7fa7fc2 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2056,7 +2056,6 @@ static int gen6_ppgtt_allocate_page_directories(struct 
i915_hw_ppgtt *ppgtt)
struct i915_address_space *vm = >base;
struct drm_i915_private *dev_priv = ppgtt->base.i915;
struct i915_ggtt *ggtt = _priv->ggtt;
-   bool retried = false;
int ret;
 
/* PPGTT PDEs reside in the GGTT and consists of 512 entries. The
@@ -2069,29 +2068,14 @@ static int gen6_ppgtt_allocate_page_directories(struct 
i915_hw_ppgtt *ppgtt)
if (ret)
return ret;
 
-alloc:
-   ret = drm_mm_insert_node_in_range_generic(>base.mm, >node,
- GEN6_PD_SIZE, GEN6_PD_ALIGN,
- I915_COLOR_UNEVICTABLE,
- 0, ggtt->base.total,
- DRM_MM_TOPDOWN);
-   if (ret == -ENOSPC && !retried) {
-   ret = i915_gem_evict_something(>base,
-  GEN6_PD_SIZE, GEN6_PD_ALIGN,
-  I915_COLOR_UNEVICTABLE,
-  0, ggtt->base.total,
-  0);
-   if (ret)
-   goto err_out;
-
-   retried = 

[Intel-gfx] [PATCH v2 09/40] drm: kselftest for drm_mm_init()

2016-12-15 Thread Chris Wilson
Simple first test to just exercise initialisation of struct drm_mm.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/selftests/drm_mm_selftests.h |   1 +
 drivers/gpu/drm/selftests/test-drm_mm.c  | 114 +++
 2 files changed, 115 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
index 1610e0a63a5b..844dd29db540 100644
--- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -6,3 +6,4 @@
  * Tests are executed in order by igt/drm_mm
  */
 selftest(sanitycheck, igt_sanitycheck) /* keep first (selfcheck for igt) */
+selftest(init, igt_init)
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c 
b/drivers/gpu/drm/selftests/test-drm_mm.c
index 4c061baccf28..ccef8e249d37 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -24,6 +24,120 @@ static int igt_sanitycheck(void *ignored)
return 0;
 }
 
+static bool assert_no_holes(const struct drm_mm *mm)
+{
+   struct drm_mm_node *hole;
+   u64 hole_start, hole_end;
+   unsigned long count;
+
+   count = 0;
+   drm_mm_for_each_hole(hole, mm, hole_start, hole_end)
+   count++;
+   if (count) {
+   pr_err("Expected to find no holes (after reserve), found %lu 
instead\n", count);
+   return false;
+   }
+
+   drm_mm_for_each_node(hole, mm) {
+   if (hole->hole_follows) {
+   pr_err("Hole follows node, expected none!\n");
+   return false;
+   }
+   }
+
+   return true;
+}
+
+static bool assert_one_hole(const struct drm_mm *mm, u64 start, u64 end)
+{
+   struct drm_mm_node *hole;
+   u64 hole_start, hole_end;
+   unsigned long count;
+   bool ok = true;
+
+   if (end <= start)
+   return true;
+
+   count = 0;
+   drm_mm_for_each_hole(hole, mm, hole_start, hole_end) {
+   if (start != hole_start || end != hole_end) {
+   if (ok)
+   pr_err("empty mm has incorrect hole, found 
(%llx, %llx), expect (%llx, %llx)\n",
+  hole_start, hole_end,
+  start, end);
+   ok = false;
+   }
+   count++;
+   }
+   if (count != 1) {
+   pr_err("Expected to find one hole, found %lu instead\n", count);
+   ok = false;
+   }
+
+   return ok;
+}
+
+static int igt_init(void *ignored)
+{
+   const unsigned int size = 4096;
+   struct drm_mm mm;
+   struct drm_mm_node tmp;
+   int ret = -EINVAL;
+
+   /* Start with some simple checks on initialising the struct drm_mm */
+   memset(, 0, sizeof(mm));
+   if (drm_mm_initialized()) {
+   pr_err("zeroed mm claims to be initialized\n");
+   return ret;
+   }
+
+   memset(, 0xff, sizeof(mm));
+   drm_mm_init(, 0, size);
+   if (!drm_mm_initialized()) {
+   pr_err("mm claims not to be initialized\n");
+   goto out;
+   }
+
+   if (!drm_mm_clean()) {
+   pr_err("mm not empty on creation\n");
+   goto out;
+   }
+
+   /* After creation, it should all be one massive hole */
+   if (!assert_one_hole(, 0, size)) {
+   ret = -EINVAL;
+   goto out;
+   }
+
+   memset(, 0, sizeof(tmp));
+   tmp.start = 0;
+   tmp.size = size;
+   ret = drm_mm_reserve_node(, );
+   if (ret) {
+   pr_err("failed to reserve whole drm_mm\n");
+   goto out;
+   }
+
+   /* After filling the range entirely, there should be no holes */
+   if (!assert_no_holes()) {
+   ret = -EINVAL;
+   goto out;
+   }
+
+   /* And then after emptying it again, the massive hole should be back */
+   drm_mm_remove_node();
+   if (!assert_one_hole(, 0, size)) {
+   ret = -EINVAL;
+   goto out;
+   }
+
+out:
+   if (ret)
+   drm_mm_debug_table(, __func__);
+   drm_mm_takedown();
+   return ret;
+}
+
 #include "drm_selftest.c"
 
 static int __init test_drm_mm_init(void)
-- 
2.11.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 06/40] drm: Add some kselftests for the DRM range manager (struct drm_mm)

2016-12-15 Thread Chris Wilson
First we introduce a smattering of infrastructure for writing selftests.
The idea is that we have a test module that exercises a particular
portion of the exported API, and that module provides a set of tests
that can either be run as an ensemble via kselftest or individually via
an igt harness (in this case igt/drm_mm). To accommodate selecting
individual tests, we export a boolean parameter to control selection of
each test - that is hidden inside a bunch of reusable boilerplate macros
to keep writing the tests simple.

v2: Choose a random random_seed unless one is specified by the user.
v3: More parameters to control max_iterations and max_prime of the
tests.

Testcase: igt/drm_mm
Signed-off-by: Chris Wilson 
Acked-by: Christian König 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/Kconfig   |  13 +++
 drivers/gpu/drm/Makefile  |   2 +
 drivers/gpu/drm/selftests/drm_mm_selftests.h  |   8 ++
 drivers/gpu/drm/selftests/drm_selftest.c  | 109 ++
 drivers/gpu/drm/selftests/drm_selftest.h  |  41 ++
 drivers/gpu/drm/selftests/test-drm_mm.c   |  55 +
 tools/testing/selftests/drivers/gpu/drm_mm.sh |  15 
 7 files changed, 243 insertions(+)
 create mode 100644 drivers/gpu/drm/selftests/drm_mm_selftests.h
 create mode 100644 drivers/gpu/drm/selftests/drm_selftest.c
 create mode 100644 drivers/gpu/drm/selftests/drm_selftest.h
 create mode 100644 drivers/gpu/drm/selftests/test-drm_mm.c
 create mode 100755 tools/testing/selftests/drivers/gpu/drm_mm.sh

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index ebfe8404c25f..d1363d21d3d1 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -48,6 +48,19 @@ config DRM_DEBUG_MM
 
  If in doubt, say "N".
 
+config DRM_DEBUG_MM_SELFTEST
+   tristate "kselftests for DRM range manager (struct drm_mm)"
+   depends on DRM
+   depends on DEBUG_KERNEL
+   default n
+   help
+ This option provides a kernel module that can be used to test
+ the DRM range manager (drm_mm) and its API. This option is not
+ useful for distributions or general kernels, but only for kernel
+ developers working on DRM and associated drivers.
+
+ If in doubt, say "N".
+
 config DRM_KMS_HELPER
tristate
depends on DRM
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index b9ae4280de9d..c8aed3688b20 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -18,6 +18,8 @@ drm-y   :=drm_auth.o drm_bufs.o drm_cache.o \
drm_plane.o drm_color_mgmt.o drm_print.o \
drm_dumb_buffers.o drm_mode_config.o
 
+obj-$(CONFIG_DRM_DEBUG_MM_SELFTEST) += selftests/test-drm_mm.o
+
 drm-$(CONFIG_COMPAT) += drm_ioc32.o
 drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
 drm-$(CONFIG_PCI) += ati_pcigart.o
diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h 
b/drivers/gpu/drm/selftests/drm_mm_selftests.h
new file mode 100644
index ..1610e0a63a5b
--- /dev/null
+++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
@@ -0,0 +1,8 @@
+/* List each unit test as selftest(name, function)
+ *
+ * The name is used as both an enum and expanded as igt__name to create
+ * a module parameter. It must be unique and legal for a C identifier.
+ *
+ * Tests are executed in order by igt/drm_mm
+ */
+selftest(sanitycheck, igt_sanitycheck) /* keep first (selfcheck for igt) */
diff --git a/drivers/gpu/drm/selftests/drm_selftest.c 
b/drivers/gpu/drm/selftests/drm_selftest.c
new file mode 100644
index ..844d4625931e
--- /dev/null
+++ b/drivers/gpu/drm/selftests/drm_selftest.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+

[Intel-gfx] [PATCH v2 03/40] drm: Add drm_mm_for_each_node_safe()

2016-12-15 Thread Chris Wilson
A complement to drm_mm_for_each_node(), wraps list_for_each_entry_safe()
for walking the list of nodes safe against removal.

Signed-off-by: Chris Wilson 
Reviewed-by: Joonas Lahtinen 
---
 drivers/gpu/drm/drm_mm.c |  9 -
 include/drm/drm_mm.h | 19 ---
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index ca1e344f318d..6e0735539545 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -138,7 +138,7 @@ static void show_leaks(struct drm_mm *mm)
if (!buf)
return;
 
-   list_for_each_entry(node, >head_node.node_list, node_list) {
+   list_for_each_entry(node, __drm_mm_nodes(mm), node_list) {
struct stack_trace trace = {
.entries = entries,
.max_entries = STACKDEPTH
@@ -320,8 +320,7 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct 
drm_mm_node *node)
if (hole->start < end)
return -ENOSPC;
} else {
-   hole = list_entry(>head_node.node_list,
- typeof(*hole), node_list);
+   hole = list_entry(__drm_mm_nodes(mm), typeof(*hole), node_list);
}
 
hole = list_last_entry(>node_list, typeof(*hole), node_list);
@@ -884,7 +883,7 @@ EXPORT_SYMBOL(drm_mm_scan_remove_block);
  */
 bool drm_mm_clean(struct drm_mm * mm)
 {
-   struct list_head *head = >head_node.node_list;
+   struct list_head *head = __drm_mm_nodes(mm);
 
return (head->next->next == head);
 }
@@ -930,7 +929,7 @@ EXPORT_SYMBOL(drm_mm_init);
  */
 void drm_mm_takedown(struct drm_mm *mm)
 {
-   if (WARN(!list_empty(>head_node.node_list),
+   if (WARN(!list_empty(__drm_mm_nodes(mm)),
 "Memory manager not clean during takedown.\n"))
show_leaks(mm);
 
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index 0b8371795aeb..0cc1b78c9ec2 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -179,6 +179,8 @@ static inline u64 drm_mm_hole_node_end(struct drm_mm_node 
*hole_node)
return __drm_mm_hole_node_end(hole_node);
 }
 
+#define __drm_mm_nodes(mm) (&(mm)->head_node.node_list)
+
 /**
  * drm_mm_for_each_node - iterator to walk over all allocated nodes
  * @entry: drm_mm_node structure to assign to in each iteration step
@@ -187,9 +189,20 @@ static inline u64 drm_mm_hole_node_end(struct drm_mm_node 
*hole_node)
  * This iterator walks over all nodes in the range allocator. It is implemented
  * with list_for_each, so not save against removal of elements.
  */
-#define drm_mm_for_each_node(entry, mm) list_for_each_entry(entry, \
-   &(mm)->head_node.node_list, \
-   node_list)
+#define drm_mm_for_each_node(entry, mm) \
+   list_for_each_entry(entry, __drm_mm_nodes(mm), node_list)
+
+/**
+ * drm_mm_for_each_node_safe - iterator to walk over all allocated nodes
+ * @entry: drm_mm_node structure to assign to in each iteration step
+ * @next: drm_mm_node structure to store the next step
+ * @mm: drm_mm allocator to walk
+ *
+ * This iterator walks over all nodes in the range allocator. It is implemented
+ * with list_for_each_safe, so save against removal of elements.
+ */
+#define drm_mm_for_each_node_safe(entry, next, mm) \
+   list_for_each_entry_safe(entry, next, __drm_mm_nodes(mm), node_list)
 
 #define __drm_mm_for_each_hole(entry, mm, hole_start, hole_end, backwards) \
for (entry = list_entry((backwards) ? (mm)->hole_stack.prev : 
(mm)->hole_stack.next, struct drm_mm_node, hole_stack); \
-- 
2.11.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 08/40] drm: Add a simple prime number generator

2016-12-15 Thread Chris Wilson
Prime numbers are interesting for testing components that use multiplies
and divides, such as testing struct drm_mm alignment computations.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/Kconfig |   4 +
 drivers/gpu/drm/Makefile|   1 +
 drivers/gpu/drm/lib/drm_prime_numbers.c | 175 
 drivers/gpu/drm/lib/drm_prime_numbers.h |  10 ++
 4 files changed, 190 insertions(+)
 create mode 100644 drivers/gpu/drm/lib/drm_prime_numbers.c
 create mode 100644 drivers/gpu/drm/lib/drm_prime_numbers.h

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 2e6ae95459e4..93895898d596 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -53,6 +53,7 @@ config DRM_DEBUG_MM_SELFTEST
depends on DRM
depends on DEBUG_KERNEL
select DRM_LIB_RANDOM
+   select DRM_LIB_PRIMES
default n
help
  This option provides a kernel module that can be used to test
@@ -340,3 +341,6 @@ config DRM_LIB_RANDOM
bool
default n
 
+config DRM_LIB_PRIMES
+   bool
+   default n
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 0fa16275fdae..bbd390fa8914 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -19,6 +19,7 @@ drm-y   :=drm_auth.o drm_bufs.o drm_cache.o \
drm_dumb_buffers.o drm_mode_config.o
 
 drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
+obj-$(CONFIG_DRM_LIB_PRIMES) += lib/drm_prime_numbers.o
 obj-$(CONFIG_DRM_DEBUG_MM_SELFTEST) += selftests/test-drm_mm.o
 
 drm-$(CONFIG_COMPAT) += drm_ioc32.o
diff --git a/drivers/gpu/drm/lib/drm_prime_numbers.c 
b/drivers/gpu/drm/lib/drm_prime_numbers.c
new file mode 100644
index ..839563d9b787
--- /dev/null
+++ b/drivers/gpu/drm/lib/drm_prime_numbers.c
@@ -0,0 +1,175 @@
+#include 
+#include 
+#include 
+
+#include "drm_prime_numbers.h"
+
+static DEFINE_MUTEX(lock);
+
+static struct primes {
+   struct rcu_head rcu;
+   unsigned long last, sz;
+   unsigned long primes[];
+} __rcu *primes;
+
+static bool slow_is_prime_number(unsigned long x)
+{
+   unsigned long y = int_sqrt(x) + 1;
+
+   while (y > 1) {
+   if ((x % y) == 0)
+   break;
+   y--;
+   }
+
+   return y == 1;
+}
+
+static unsigned long slow_next_prime_number(unsigned long x)
+{
+   for (;;) {
+   if (slow_is_prime_number(++x))
+   return x;
+   }
+}
+
+static unsigned long mark_multiples(unsigned long x,
+   unsigned long *p,
+   unsigned long start,
+   unsigned long end)
+{
+   unsigned long m;
+
+   m = 2 * x;
+   if (m < start)
+   m = (start / x + 1) * x;
+
+   while (m < end) {
+   __clear_bit(m, p);
+   m += x;
+   }
+
+   return x;
+}
+
+static struct primes *expand(unsigned long x)
+{
+   unsigned long sz, y, prev;
+   struct primes *p, *new;
+
+   sz = x * x;
+   if (sz < x)
+   return NULL;
+
+   mutex_lock();
+   p = rcu_dereference_protected(primes, lockdep_is_held());
+   if (p && x < p->last)
+   goto unlock;
+
+   sz = round_up(sz, BITS_PER_LONG);
+   new = kmalloc(sizeof(*new) + sz / sizeof(long), GFP_KERNEL);
+   if (!new) {
+   p = NULL;
+   goto unlock;
+   }
+
+   /* Where memory permits, track the primes using the
+* Sieve of Eratosthenes.
+*/
+   if (p) {
+   prev = p->sz;
+   memcpy(new->primes, p->primes, prev / BITS_PER_LONG);
+   } else {
+   prev = 0;
+   }
+   memset(new->primes + prev / BITS_PER_LONG,
+  0xff, (sz - prev) / sizeof(long));
+   for (y = 2UL; y < sz; y = find_next_bit(new->primes, sz, y + 1))
+   new->last = mark_multiples(y, new->primes, prev, sz);
+   new->sz = sz;
+
+   rcu_assign_pointer(primes, new);
+   if (p)
+   kfree_rcu(p, rcu);
+   p = new;
+
+unlock:
+   mutex_unlock();
+   return p;
+}
+
+unsigned long drm_next_prime_number(unsigned long x)
+{
+   struct primes *p;
+
+   if (x < 2)
+   return 2;
+
+   rcu_read_lock();
+   p = rcu_dereference(primes);
+   if (!p || x >= p->last) {
+   rcu_read_unlock();
+
+   p = expand(x);
+   if (!p)
+   return slow_next_prime_number(x);
+
+   rcu_read_lock();
+   }
+
+   x = find_next_bit(p->primes, p->last, x + 1);
+   rcu_read_unlock();
+
+   return x;
+}
+EXPORT_SYMBOL(drm_next_prime_number);
+
+bool drm_is_prime_number(unsigned long x)
+{
+   struct primes *p;
+   bool result;
+
+   switch (x) {
+   case 0:
+   return false;
+   case 1:
+ 

[Intel-gfx] drm_mm range manager fixes, take 2

2016-12-15 Thread Chris Wilson
The goal of this series is to fix top-down allocations to be allocated
from the top and aligned correctly, introduce bottom-up allocations, and
speed up searches and tighten evictions.

More polish on the test cases to reduce code duplication and to improve
expectation checking. And a little more polish on the patches leading up
to the fixes.
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [kbuild-all] [PATCH] drm: Convert all helpers to drm_connector_list_iter

2016-12-15 Thread Fengguang Wu

Hi Daniel,

On Fri, Dec 16, 2016 at 08:29:43AM +0100, Daniel Vetter wrote:

Hi Kbuild folks

So yeah this doesn't apply because it's just 1 patch resent out of a
big patch series, in-reply-to the patch it replaces. So applying this
alone and telling me (and all the mailing lists) that it doesn't apply
isn't all that useful.

And it shouldn't be too hard to detect this, since the fdo patchwork
instance does catch most of these partial resends successfully and
correctly, and will retest the entire patch series.


Good point! CC Xiaolong. This scenario seems happen frequent enough in
LKML to worth the efforts to add auto detect logic for.

Thanks,
Fengguang


On Thu, Dec 15, 2016 at 11:59 PM, kbuild test robot <l...@intel.com> wrote:

Hi Daniel,

[auto build test ERROR on drm/drm-next]
[also build test ERROR on next-20161215]
[cannot apply to v4.9]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Daniel-Vetter/drm-Convert-all-helpers-to-drm_connector_list_iter/20161216-061508
base:   git://people.freedesktop.org/~airlied/linux.git drm-next
config: i386-randconfig-x003-201650 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=i386

All error/warnings (new ones prefixed by >>):

   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_helper_encoder_in_use':

drivers/gpu/drm/drm_crtc_helper.c:91:33: error: storage size of 'conn_iter' 
isn't known

 struct drm_connector_list_iter conn_iter;
^

drivers/gpu/drm/drm_crtc_helper.c:104:2: error: implicit declaration of 
function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]

 drm_connector_list_iter_get(dev, _iter);
 ^~~

drivers/gpu/drm/drm_crtc_helper.c:105:2: error: implicit declaration of 
function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]

 drm_for_each_connector_iter(connector, _iter) {
 ^~~

drivers/gpu/drm/drm_crtc_helper.c:105:53: error: expected ';' before '{' token

 drm_for_each_connector_iter(connector, _iter) {
^
   drivers/gpu/drm/drm_crtc_helper.c:91:33: warning: unused variable 
'conn_iter' [-Wunused-variable]
 struct drm_connector_list_iter conn_iter;
^
   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_crtc_helper_disable':
   drivers/gpu/drm/drm_crtc_helper.c:446:34: error: storage size of 'conn_iter' 
isn't known
  struct drm_connector_list_iter conn_iter;
 ^
   drivers/gpu/drm/drm_crtc_helper.c:452:54: error: expected ';' before '{' 
token
  drm_for_each_connector_iter(connector, _iter) {
 ^
   drivers/gpu/drm/drm_crtc_helper.c:446:34: warning: unused variable 
'conn_iter' [-Wunused-variable]
  struct drm_connector_list_iter conn_iter;
 ^
   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_crtc_helper_set_config':
   drivers/gpu/drm/drm_crtc_helper.c:521:33: error: storage size of 'conn_iter' 
isn't known
 struct drm_connector_list_iter conn_iter;
^

drivers/gpu/drm/drm_crtc_helper.c:588:3: error: expected ';' before 
'save_connector_encoders'

  save_connector_encoders[count++] = connector->encoder;
  ^~~

drivers/gpu/drm/drm_crtc_helper.c:589:2: error: implicit declaration of 
function 'drm_connector_list_iter_put' [-Werror=implicit-function-declaration]

 drm_connector_list_iter_put(_iter);
 ^~~
   drivers/gpu/drm/drm_crtc_helper.c:633:53: error: expected ';' before '{' 
token
 drm_for_each_connector_iter(connector, _iter) {
^
   drivers/gpu/drm/drm_crtc_helper.c:675:53: error: expected ';' before '{' 
token
 drm_for_each_connector_iter(connector, _iter) {
^

drivers/gpu/drm/drm_crtc_helper.c:767:3: error: expected ';' before 'connector'

  connector->encoder = save_connector_encoders[count++];
  ^
   drivers/gpu/drm/drm_crtc_helper.c:521:33: warning: unused variable 
'conn_iter' [-Wunused-variable]
 struct drm_connector_list_iter conn_iter;
^
   drivers/gpu/drm/drm_crtc_helper.c:517:49: warning: unused variable 
'new_encoder' [-Wunused-variable]
 struct drm_encoder **save_connector_encoders, *new_encoder, *encoder;
^~~
   drivers/gpu/drm/drm_crtc_helper.c:516:41: warning: unused variable 
'new_crtc' [-Wunused-variable]
 struct drm_crtc **

Re: [Intel-gfx] ✗ Fi.CI.BAT: failure for drm/i915: relax uncritical udelay_range() settings

2016-12-15 Thread Saarinen, Jani
> == Series Details ==
> 
> Series: drm/i915: relax uncritical udelay_range() settings
> URL   : https://patchwork.freedesktop.org/series/16900/
> State : failure
> 
> == Summary ==
> 
> Series 16900v1 drm/i915: relax uncritical udelay_range() settings
> https://patchwork.freedesktop.org/api/1.0/series/16900/revisions/1/mbox/
> 
> Test gem_ringfill:
> Subgroup basic-default-hang:
> pass   -> INCOMPLETE (fi-hsw-4770)
running: igt/gem_ringfill/basic-default-hang
[117/247] skip: 8, pass: 109 /  
Build timed out (after 17 minutes). Marking the build as aborted.

> Test gem_sync:
> Subgroup basic-store-all:
> pass   -> FAIL   (fi-ivb-3520m)

Err 
(gem_sync:9405) CRITICAL: Test assertion failure function store_all, file 
gem_sync.c:690:
(gem_sync:9405) CRITICAL: Failed assertion: 
intel_detect_and_clear_missed_interrupts(fd) == 0
(gem_sync:9405) CRITICAL: error: 1 != 0
Subtest basic-store-all failed.
> 
> fi-bdw-5557u total:247  pass:233  dwarn:0   dfail:0   fail:0   skip:14
> fi-bsw-n3050 total:247  pass:208  dwarn:0   dfail:0   fail:0   skip:39
> fi-bxt-j4205 total:247  pass:222  dwarn:0   dfail:0   fail:0   skip:25
> fi-byt-j1900 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27
> fi-byt-n2820 total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31
> fi-hsw-4770  total:118  pass:109  dwarn:0   dfail:0   fail:0   skip:8
> fi-hsw-4770r total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19
> fi-ilk-650   total:247  pass:195  dwarn:0   dfail:0   fail:0   skip:52
> fi-ivb-3520m total:247  pass:225  dwarn:0   dfail:0   fail:1   skip:21
> fi-kbl-7500u total:247  pass:226  dwarn:0   dfail:0   fail:0   skip:21
> fi-skl-6260u total:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13
> fi-skl-6700hqtotal:247  pass:227  dwarn:0   dfail:0   fail:0   skip:20
> fi-skl-6700k total:247  pass:224  dwarn:3   dfail:0   fail:0   skip:20
> fi-skl-6770hqtotal:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13
> fi-snb-2520m total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31
> fi-snb-2600  total:247  pass:215  dwarn:0   dfail:0   fail:0   skip:32
> 
> 639f10d1159e87cac2f85769dcd081520b904f56 drm-tip: 2016y-12m-15d-17h-
> 57m-41s UTC integration manifest
> 69bb294 drm/i915: relax uncritical udelay_range() settings
> 
> == Logs ==
> 
> For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_3304/


Jani Saarinen
Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo


___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm: Convert all helpers to drm_connector_list_iter

2016-12-15 Thread Daniel Vetter
Hi Kbuild folks

So yeah this doesn't apply because it's just 1 patch resent out of a
big patch series, in-reply-to the patch it replaces. So applying this
alone and telling me (and all the mailing lists) that it doesn't apply
isn't all that useful.

And it shouldn't be too hard to detect this, since the fdo patchwork
instance does catch most of these partial resends successfully and
correctly, and will retest the entire patch series.
-Daniel


On Thu, Dec 15, 2016 at 11:59 PM, kbuild test robot <l...@intel.com> wrote:
> Hi Daniel,
>
> [auto build test ERROR on drm/drm-next]
> [also build test ERROR on next-20161215]
> [cannot apply to v4.9]
> [if your patch is applied to the wrong git tree, please drop us a note to 
> help improve the system]
>
> url:
> https://github.com/0day-ci/linux/commits/Daniel-Vetter/drm-Convert-all-helpers-to-drm_connector_list_iter/20161216-061508
> base:   git://people.freedesktop.org/~airlied/linux.git drm-next
> config: i386-randconfig-x003-201650 (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=i386
>
> All error/warnings (new ones prefixed by >>):
>
>drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_helper_encoder_in_use':
>>> drivers/gpu/drm/drm_crtc_helper.c:91:33: error: storage size of 'conn_iter' 
>>> isn't known
>  struct drm_connector_list_iter conn_iter;
> ^
>>> drivers/gpu/drm/drm_crtc_helper.c:104:2: error: implicit declaration of 
>>> function 'drm_connector_list_iter_get' 
>>> [-Werror=implicit-function-declaration]
>  drm_connector_list_iter_get(dev, _iter);
>  ^~~
>>> drivers/gpu/drm/drm_crtc_helper.c:105:2: error: implicit declaration of 
>>> function 'drm_for_each_connector_iter' 
>>> [-Werror=implicit-function-declaration]
>  drm_for_each_connector_iter(connector, _iter) {
>  ^~~
>>> drivers/gpu/drm/drm_crtc_helper.c:105:53: error: expected ';' before '{' 
>>> token
>  drm_for_each_connector_iter(connector, _iter) {
> ^
>drivers/gpu/drm/drm_crtc_helper.c:91:33: warning: unused variable 
> 'conn_iter' [-Wunused-variable]
>  struct drm_connector_list_iter conn_iter;
> ^
>drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_crtc_helper_disable':
>drivers/gpu/drm/drm_crtc_helper.c:446:34: error: storage size of 
> 'conn_iter' isn't known
>   struct drm_connector_list_iter conn_iter;
>  ^
>drivers/gpu/drm/drm_crtc_helper.c:452:54: error: expected ';' before '{' 
> token
>   drm_for_each_connector_iter(connector, _iter) {
>  ^
>drivers/gpu/drm/drm_crtc_helper.c:446:34: warning: unused variable 
> 'conn_iter' [-Wunused-variable]
>   struct drm_connector_list_iter conn_iter;
>  ^
>drivers/gpu/drm/drm_crtc_helper.c: In function 
> 'drm_crtc_helper_set_config':
>drivers/gpu/drm/drm_crtc_helper.c:521:33: error: storage size of 
> 'conn_iter' isn't known
>  struct drm_connector_list_iter conn_iter;
> ^
>>> drivers/gpu/drm/drm_crtc_helper.c:588:3: error: expected ';' before 
>>> 'save_connector_encoders'
>   save_connector_encoders[count++] = connector->encoder;
>   ^~~
>>> drivers/gpu/drm/drm_crtc_helper.c:589:2: error: implicit declaration of 
>>> function 'drm_connector_list_iter_put' 
>>> [-Werror=implicit-function-declaration]
>  drm_connector_list_iter_put(_iter);
>  ^~~
>drivers/gpu/drm/drm_crtc_helper.c:633:53: error: expected ';' before '{' 
> token
>  drm_for_each_connector_iter(connector, _iter) {
> ^
>drivers/gpu/drm/drm_crtc_helper.c:675:53: error: expected ';' before '{' 
> token
>  drm_for_each_connector_iter(connector, _iter) {
> ^
>>> drivers/gpu/drm/drm_crtc_helper.c:767:3: error: expected ';' before 
>>> 'connector'
>   connector->encoder = save_connector_encoders[count++];
>   ^
>drivers/gpu/drm/drm_crtc_helper.c:521:33: warning: unused variable 
> 'conn_iter' [-Wunused-variable]
>  struct drm_connector_list_iter conn_iter;
> ^
>drivers/gpu/drm/drm_crtc_h

[Intel-gfx] ✗ Fi.CI.BAT: warning for series starting with [1/2] drm/i915: Check num_pipes before initializing audio component

2016-12-15 Thread Patchwork
== Series Details ==

Series: series starting with [1/2] drm/i915: Check num_pipes before 
initializing audio component
URL   : https://patchwork.freedesktop.org/series/16902/
State : warning

== Summary ==

Series 16902v1 Series without cover letter
https://patchwork.freedesktop.org/api/1.0/series/16902/revisions/1/mbox/

Test kms_force_connector_basic:
Subgroup force-connector-state:
pass   -> SKIP   (fi-snb-2520m)

fi-bdw-5557u total:247  pass:233  dwarn:0   dfail:0   fail:0   skip:14 
fi-bsw-n3050 total:247  pass:208  dwarn:0   dfail:0   fail:0   skip:39 
fi-bxt-j4205 total:247  pass:222  dwarn:0   dfail:0   fail:0   skip:25 
fi-bxt-t5700 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
fi-byt-j1900 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
fi-byt-n2820 total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31 
fi-hsw-4770  total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19 
fi-hsw-4770r total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19 
fi-ilk-650   total:247  pass:195  dwarn:0   dfail:0   fail:0   skip:52 
fi-ivb-3520m total:247  pass:226  dwarn:0   dfail:0   fail:0   skip:21 
fi-kbl-7500u total:247  pass:226  dwarn:0   dfail:0   fail:0   skip:21 
fi-skl-6260u total:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13 
fi-skl-6700hqtotal:247  pass:227  dwarn:0   dfail:0   fail:0   skip:20 
fi-skl-6700k total:247  pass:224  dwarn:3   dfail:0   fail:0   skip:20 
fi-skl-6770hqtotal:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13 
fi-snb-2520m total:247  pass:215  dwarn:0   dfail:0   fail:0   skip:32 
fi-snb-2600  total:247  pass:215  dwarn:0   dfail:0   fail:0   skip:32 

639f10d1159e87cac2f85769dcd081520b904f56 drm-tip: 2016y-12m-15d-17h-57m-41s UTC 
integration manifest
9bd18fd drm/i915: Check num_pipes before initializing or calling display hooks
273e44e drm/i915: Check num_pipes before initializing audio component

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_3305/
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 2/2] drm/i915: Check num_pipes before initializing or calling display hooks

2016-12-15 Thread Wang Elaine
From: Elaine Wang 

when num_pipes is zero, it indicates display doesn't exist, so there
is no need to initialize display hooks. And to avoid calling these
uninitialized display hooks, respect num_pipes at the beginning of
intel_modeset_init_hw and intel_init_clock_gating.

intel_init_pm() calls FBC init function and then initializes
water mark hooks. Both aren't needed when display doesn't exist. So
check num_pipes before invoking intel_init_pm().

Cc: Chris Wilson 
Cc: Joonas Lahtinen 
Signed-off-by: Elaine Wang 
---
 drivers/gpu/drm/i915/intel_display.c | 9 +++--
 drivers/gpu/drm/i915/intel_pm.c  | 7 ++-
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 9cc5dbf..26ecf08 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -16030,6 +16030,9 @@ static void intel_atomic_state_free(struct 
drm_atomic_state *state)
  */
 void intel_init_display_hooks(struct drm_i915_private *dev_priv)
 {
+   if (INTEL_INFO(dev_priv)->num_pipes == 0)
+   return;
+
if (INTEL_INFO(dev_priv)->gen >= 9) {
dev_priv->display.get_pipe_config = haswell_get_pipe_config;
dev_priv->display.get_initial_plane_config =
@@ -16412,6 +16415,9 @@ void intel_modeset_init_hw(struct drm_device *dev)
 {
struct drm_i915_private *dev_priv = to_i915(dev);
 
+   if (INTEL_INFO(dev_priv)->num_pipes == 0)
+   return;
+
intel_update_cdclk(dev_priv);
 
dev_priv->atomic_cdclk_freq = dev_priv->cdclk_freq;
@@ -16524,11 +16530,10 @@ int intel_modeset_init(struct drm_device *dev)
 
intel_init_quirks(dev);
 
-   intel_init_pm(dev_priv);
-
if (INTEL_INFO(dev_priv)->num_pipes == 0)
return 0;
 
+   intel_init_pm(dev_priv);
/*
 * There may be no VBT; and if the BIOS enabled SSC we can
 * just keep using it to avoid unnecessary flicker.  Whereas if the
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index d0834b3..cf66e57 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -7619,7 +7619,8 @@ static void i830_init_clock_gating(struct 
drm_i915_private *dev_priv)
 
 void intel_init_clock_gating(struct drm_i915_private *dev_priv)
 {
-   dev_priv->display.init_clock_gating(dev_priv);
+   if (INTEL_INFO(dev_priv)->num_pipes)
+   dev_priv->display.init_clock_gating(dev_priv);
 }
 
 void intel_suspend_hw(struct drm_i915_private *dev_priv)
@@ -7644,6 +7645,10 @@ static void nop_init_clock_gating(struct 
drm_i915_private *dev_priv)
  */
 void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv)
 {
+
+   if (INTEL_INFO(dev_priv)->num_pipes == 0)
+   return;
+
if (IS_SKYLAKE(dev_priv))
dev_priv->display.init_clock_gating = skylake_init_clock_gating;
else if (IS_KABYLAKE(dev_priv))
-- 
1.9.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 1/2] drm/i915: Check num_pipes before initializing audio component

2016-12-15 Thread Wang Elaine
From: Elaine Wang 

when num_pipes is zero, it indicates there is no display and HDMI
audio doesn't exist.

Cc: Chris Wilson 
Cc: Joonas Lahtinen 
Signed-off-by: Elaine Wang 
---
 drivers/gpu/drm/i915/i915_drv.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 6428588..c94e26d 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1132,7 +1132,8 @@ static void i915_driver_register(struct drm_i915_private 
*dev_priv)
if (IS_GEN5(dev_priv))
intel_gpu_ips_init(dev_priv);
 
-   i915_audio_component_init(dev_priv);
+   if (INTEL_INFO(dev_priv)->num_pipes)
+   i915_audio_component_init(dev_priv);
 
/*
 * Some ports require correctly set-up hpd registers for detection to
-- 
1.9.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] Guc parameter Handling

2016-12-15 Thread Zhenyu Wang
On 2016.12.15 22:36:40 +, Srivatsa, Anusha wrote:
> Hi All,
> 
>  
> 
> I was wondering if we intend to keep -1 and 2 for the enable_guc_submission
> parameter. Since now we are gating guc loads if either guc_submission or
> enable_huc parameter is set, why have a -1(platform default) and 2(forcefully
> load) option? We anyway do not have any special default set per platform. For
> now the default is 0 on all platforms. Moving forward if GuC gets more stable
> and we want to set a default to a certain platform, we can add -1 then.
> 
>  
> 
> Also, why have a 2? We can use enable_guc_submission=1 in order to make sure
> the guc is loaded and guc_submission is enabled and set 
> enable_guc_submission=0
> to make sure guc submission is not used.
> 
>  
> 
> Any thought on this?
> 
>  

For gvt, we need to disable guc submission in guest on current hw.
I just want to send one using current enable_guc_loading but if changed
to guc_submission/enable_huc later, I'll hold till that settle down.

To support HuC for guest, we will need to add extra pvinfo, so won't
allow guest kernel to load huc firmware but tell guest driver that HuC
is ready for use.

thanks

-- 
Open Source Technology Center, Intel ltd.

$gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827


signature.asc
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] ✗ Fi.CI.BAT: failure for drm/i915: relax uncritical udelay_range() settings

2016-12-15 Thread Patchwork
== Series Details ==

Series: drm/i915: relax uncritical udelay_range() settings
URL   : https://patchwork.freedesktop.org/series/16900/
State : failure

== Summary ==

Series 16900v1 drm/i915: relax uncritical udelay_range() settings
https://patchwork.freedesktop.org/api/1.0/series/16900/revisions/1/mbox/

Test gem_ringfill:
Subgroup basic-default-hang:
pass   -> INCOMPLETE (fi-hsw-4770)
Test gem_sync:
Subgroup basic-store-all:
pass   -> FAIL   (fi-ivb-3520m)

fi-bdw-5557u total:247  pass:233  dwarn:0   dfail:0   fail:0   skip:14 
fi-bsw-n3050 total:247  pass:208  dwarn:0   dfail:0   fail:0   skip:39 
fi-bxt-j4205 total:247  pass:222  dwarn:0   dfail:0   fail:0   skip:25 
fi-byt-j1900 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
fi-byt-n2820 total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31 
fi-hsw-4770  total:118  pass:109  dwarn:0   dfail:0   fail:0   skip:8  
fi-hsw-4770r total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19 
fi-ilk-650   total:247  pass:195  dwarn:0   dfail:0   fail:0   skip:52 
fi-ivb-3520m total:247  pass:225  dwarn:0   dfail:0   fail:1   skip:21 
fi-kbl-7500u total:247  pass:226  dwarn:0   dfail:0   fail:0   skip:21 
fi-skl-6260u total:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13 
fi-skl-6700hqtotal:247  pass:227  dwarn:0   dfail:0   fail:0   skip:20 
fi-skl-6700k total:247  pass:224  dwarn:3   dfail:0   fail:0   skip:20 
fi-skl-6770hqtotal:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13 
fi-snb-2520m total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31 
fi-snb-2600  total:247  pass:215  dwarn:0   dfail:0   fail:0   skip:32 

639f10d1159e87cac2f85769dcd081520b904f56 drm-tip: 2016y-12m-15d-17h-57m-41s UTC 
integration manifest
69bb294 drm/i915: relax uncritical udelay_range() settings

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_3304/
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915: relax uncritical udelay_range()

2016-12-15 Thread Patchwork
== Series Details ==

Series: drm/i915: relax uncritical udelay_range()
URL   : https://patchwork.freedesktop.org/series/16897/
State : success

== Summary ==

Series 16897v1 drm/i915: relax uncritical udelay_range()
https://patchwork.freedesktop.org/api/1.0/series/16897/revisions/1/mbox/


fi-bdw-5557u total:247  pass:233  dwarn:0   dfail:0   fail:0   skip:14 
fi-bsw-n3050 total:247  pass:208  dwarn:0   dfail:0   fail:0   skip:39 
fi-bxt-j4205 total:247  pass:222  dwarn:0   dfail:0   fail:0   skip:25 
fi-bxt-t5700 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
fi-byt-j1900 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
fi-byt-n2820 total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31 
fi-hsw-4770  total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19 
fi-hsw-4770r total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19 
fi-ilk-650   total:247  pass:195  dwarn:0   dfail:0   fail:0   skip:52 
fi-ivb-3520m total:247  pass:226  dwarn:0   dfail:0   fail:0   skip:21 
fi-kbl-7500u total:247  pass:226  dwarn:0   dfail:0   fail:0   skip:21 
fi-skl-6260u total:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13 
fi-skl-6700hqtotal:247  pass:227  dwarn:0   dfail:0   fail:0   skip:20 
fi-skl-6700k total:247  pass:224  dwarn:3   dfail:0   fail:0   skip:20 
fi-skl-6770hqtotal:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13 
fi-snb-2520m total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31 
fi-snb-2600  total:247  pass:215  dwarn:0   dfail:0   fail:0   skip:32 

639f10d1159e87cac2f85769dcd081520b904f56 drm-tip: 2016y-12m-15d-17h-57m-41s UTC 
integration manifest
83a9dc0 drm/i915: relax uncritical udelay_range()

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_3303/
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH V2] drm/i915: relax uncritical udelay_range() settings

2016-12-15 Thread Nicholas Mc Guire
udelay_range(2, 3) is inefficient and as discussions with Jani Nikula
<jani.nik...@linux.intel.com> unnecessary here. This replaces this
tight setting with a relaxed delay of min=20 and max=50. which helps
the hrtimer subsystem optimize timer handling.

Link: http://lkml.org/lkml/2016/12/15/127
Fixes: commit 37ab0810c9b7 ("drm/i915/bxt: DSI enable for BXT")
Signed-off-by: Nicholas Mc Guire <hof...@osadl.org>
---

V2: use relaxed uslee_range() rather than udelay
fix documentation of changed timings

Problem found by coccinelle:

Patch was compile tested with: x86_64_defconfig (implies CONFIG_DRM_I915)

Patch is against 4.9.0 (localversion-next is next-20161215)

 drivers/gpu/drm/i915/intel_dsi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 5b72c50..92b96fa 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -379,7 +379,8 @@ static void bxt_dsi_device_ready(struct intel_encoder 
*encoder)
val &= ~ULPS_STATE_MASK;
val |= (ULPS_STATE_ENTER | DEVICE_READY);
I915_WRITE(MIPI_DEVICE_READY(port), val);
-   usleep_range(2, 3);
+   /* at least 2us - relaxed for hrtimer subsystem optimization */
+   usleep_range(10, 50);
 
/* 3. Exit ULPS */
val = I915_READ(MIPI_DEVICE_READY(port));
-- 
2.1.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH V2] drm/i915: relax uncritical udelay_range()

2016-12-15 Thread Nicholas Mc Guire
udelay_range(1, 2) is inefficient and as discussions with Jani Nikula
<jani.nik...@linux.intel.com> unnecessary here. This replaces this
tight setting with a relaxed delay of min=20 and max=50 which helps
the hrtimer subsystem optimize timer handling.

Fixes: commit be4fc046bed3 ("drm/i915: add VLV DSI PLL Calculations") 
Link: http://lkml.org/lkml/2016/12/15/147
Signed-off-by: Nicholas Mc Guire <hof...@osadl.org>
---

V2: use relaxed uslee_range() rather than udelay
fix documentation of changed timings

Problem found by coccinelle:

Patch was compile tested with: x86_64_defconfig (implies CONFIG_DRM_I915)

Patch is against 4.9.0 (localversion-next is next-20161215)

 drivers/gpu/drm/i915/intel_dsi_pll.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c 
b/drivers/gpu/drm/i915/intel_dsi_pll.c
index 56eff60..d210bc4 100644
--- a/drivers/gpu/drm/i915/intel_dsi_pll.c
+++ b/drivers/gpu/drm/i915/intel_dsi_pll.c
@@ -156,8 +156,10 @@ static void vlv_enable_dsi_pll(struct intel_encoder 
*encoder,
vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL,
  config->dsi_pll.ctrl & ~DSI_PLL_VCO_EN);
 
-   /* wait at least 0.5 us after ungating before enabling VCO */
-   usleep_range(1, 10);
+   /* wait at least 0.5 us after ungating before enabling VCO,
+* allow hrtimer subsystem optimization by relaxing timing
+*/
+   usleep_range(10, 50);
 
vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, config->dsi_pll.ctrl);
 
-- 
2.1.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v3] drm/i915: Check HAS_PCH_NOP when install or reset dispaly IRQ

2016-12-15 Thread Wang, Elaine
> On Thu, 15 Dec 2016, Ville Syrjälä  wrote:
> > On Mon, Dec 12, 2016 at 02:57:44PM +0800, Wang Elaine wrote:
> >> From: Elaine Wang 
> >>
> >> Some platforms don't have display. To avoid accessing the
> >> non-existent registers, check HAS_PCH_NOP before invoking display IRQ
> >> install or reset function.
> >>
> >> Cc: Chris Wilson 
> >> Cc: Joonas Lahtinen 
> >> Signed-off-by: Elaine Wang 
> >> ---
> >>  drivers/gpu/drm/i915/i915_irq.c | 10 +++---
> >>  1 file changed, 7 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/i915_irq.c
> >> b/drivers/gpu/drm/i915/i915_irq.c index 0b119b9..369a038 100644
> >> --- a/drivers/gpu/drm/i915/i915_irq.c
> >> +++ b/drivers/gpu/drm/i915/i915_irq.c
> >> @@ -2990,8 +2990,10 @@ static void gen8_irq_reset(struct drm_device
> *dev)
> >>
> POWER_DOMAIN_PIPE(pipe)))
> >>GEN8_IRQ_RESET_NDX(DE_PIPE, pipe);
> >>
> >> -  GEN5_IRQ_RESET(GEN8_DE_PORT_);
> >> -  GEN5_IRQ_RESET(GEN8_DE_MISC_);
> >> +  if (!HAS_PCH_NOP(dev_priv)) {
> >> +  GEN5_IRQ_RESET(GEN8_DE_PORT_);
> >> +  GEN5_IRQ_RESET(GEN8_DE_MISC_);
> >> +  }
> >
> > Hmm. These are north side registers so looking at PCH_NOP feels
> > questionable.
> 
> Indeed, num_pipes == 0 isn't exactly the same thing as HAS_PCH_NOP.
> 
> Jani.

I thought HAS_PCH_NOP had same meaning as num_pipes == 0 because I saw following
code in i915_drv.c. Is there any exception?

https://cgit.freedesktop.org/drm-intel/tree/drivers/gpu/drm/i915/i915_drv.c?h=drm-intel-nightly#n145
static void intel_detect_pch(struct drm_i915_private *dev_priv)
{
struct pci_dev *pch = NULL;

/* In all current cases, num_pipes is equivalent to the PCH_NOP setting
 * (which really amounts to a PCH but no South Display).
 */
if (INTEL_INFO(dev_priv)->num_pipes == 0) {
dev_priv->pch_type = PCH_NOP;
return;
}

Thanks,
Elaine
> 
> 
> >
> >>GEN5_IRQ_RESET(GEN8_PCU_);
> >>
> >>if (HAS_PCH_SPLIT(dev_priv))
> >> @@ -3414,7 +3416,9 @@ static int gen8_irq_postinstall(struct drm_device
> *dev)
> >>ibx_irq_pre_postinstall(dev);
> >>
> >>gen8_gt_irq_postinstall(dev_priv);
> >> -  gen8_de_irq_postinstall(dev_priv);
> >> +
> >> +  if (!HAS_PCH_NOP(dev_priv))
> >> +  gen8_de_irq_postinstall(dev_priv);
> >>
> >>if (HAS_PCH_SPLIT(dev_priv))
> >>ibx_irq_postinstall(dev);
> >> --
> >> 1.9.1
> 
> --
> Jani Nikula, Intel Open Source Technology Center
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] ✓ Fi.CI.BAT: success for HuC Loading Patches

2016-12-15 Thread Patchwork
== Series Details ==

Series: HuC Loading Patches
URL   : https://patchwork.freedesktop.org/series/16878/
State : success

== Summary ==

Series 16878v1 HuC Loading Patches
https://patchwork.freedesktop.org/api/1.0/series/16878/revisions/1/mbox/


fi-bdw-5557u total:247  pass:233  dwarn:0   dfail:0   fail:0   skip:14 
fi-bsw-n3050 total:247  pass:208  dwarn:0   dfail:0   fail:0   skip:39 
fi-bxt-j4205 total:247  pass:222  dwarn:0   dfail:0   fail:0   skip:25 
fi-bxt-t5700 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
fi-byt-j1900 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
fi-byt-n2820 total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31 
fi-hsw-4770  total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19 
fi-hsw-4770r total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19 
fi-ilk-650   total:247  pass:195  dwarn:0   dfail:0   fail:0   skip:52 
fi-ivb-3520m total:247  pass:226  dwarn:0   dfail:0   fail:0   skip:21 
fi-kbl-7500u total:247  pass:226  dwarn:0   dfail:0   fail:0   skip:21 
fi-skl-6260u total:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13 
fi-skl-6700hqtotal:247  pass:227  dwarn:0   dfail:0   fail:0   skip:20 
fi-skl-6700k total:247  pass:224  dwarn:3   dfail:0   fail:0   skip:20 
fi-skl-6770hqtotal:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13 
fi-snb-2520m total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31 
fi-snb-2600  total:247  pass:215  dwarn:0   dfail:0   fail:0   skip:32 

639f10d1159e87cac2f85769dcd081520b904f56 drm-tip: 2016y-12m-15d-17h-57m-41s UTC 
integration manifest
0bbec17 drm/i915/get_params: Add HuC status to getparams
8f0431a drm/i915/huc: Support HuC authentication
b77b638 drm/i915/huc: Add debugfs for HuC loading status check
378c8c0 drm/i915/HuC: Add KBL huC loading Support
561449c drm/i915/huc: Add BXT HuC Loading Support
0b52fc6 drm/i915/huc: Add HuC fw loading support
c850b01 drm/i915/huc: Unified css_header struct for GuC and HuC
5ddedaa drm/i915/guc: Make the GuC fw loading helper functions general

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_3302/
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm: Convert all helpers to drm_connector_list_iter

2016-12-15 Thread kbuild test robot
Hi Daniel,

[auto build test ERROR on drm/drm-next]
[also build test ERROR on next-20161215]
[cannot apply to v4.9]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Daniel-Vetter/drm-Convert-all-helpers-to-drm_connector_list_iter/20161216-061508
base:   git://people.freedesktop.org/~airlied/linux.git drm-next
config: i386-randconfig-x003-201650 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=i386 

All error/warnings (new ones prefixed by >>):

   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_helper_encoder_in_use':
>> drivers/gpu/drm/drm_crtc_helper.c:91:33: error: storage size of 'conn_iter' 
>> isn't known
 struct drm_connector_list_iter conn_iter;
^
>> drivers/gpu/drm/drm_crtc_helper.c:104:2: error: implicit declaration of 
>> function 'drm_connector_list_iter_get' 
>> [-Werror=implicit-function-declaration]
 drm_connector_list_iter_get(dev, _iter);
 ^~~
>> drivers/gpu/drm/drm_crtc_helper.c:105:2: error: implicit declaration of 
>> function 'drm_for_each_connector_iter' 
>> [-Werror=implicit-function-declaration]
 drm_for_each_connector_iter(connector, _iter) {
 ^~~
>> drivers/gpu/drm/drm_crtc_helper.c:105:53: error: expected ';' before '{' 
>> token
 drm_for_each_connector_iter(connector, _iter) {
^
   drivers/gpu/drm/drm_crtc_helper.c:91:33: warning: unused variable 
'conn_iter' [-Wunused-variable]
 struct drm_connector_list_iter conn_iter;
^
   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_crtc_helper_disable':
   drivers/gpu/drm/drm_crtc_helper.c:446:34: error: storage size of 'conn_iter' 
isn't known
  struct drm_connector_list_iter conn_iter;
 ^
   drivers/gpu/drm/drm_crtc_helper.c:452:54: error: expected ';' before '{' 
token
  drm_for_each_connector_iter(connector, _iter) {
 ^
   drivers/gpu/drm/drm_crtc_helper.c:446:34: warning: unused variable 
'conn_iter' [-Wunused-variable]
  struct drm_connector_list_iter conn_iter;
 ^
   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_crtc_helper_set_config':
   drivers/gpu/drm/drm_crtc_helper.c:521:33: error: storage size of 'conn_iter' 
isn't known
 struct drm_connector_list_iter conn_iter;
^
>> drivers/gpu/drm/drm_crtc_helper.c:588:3: error: expected ';' before 
>> 'save_connector_encoders'
  save_connector_encoders[count++] = connector->encoder;
  ^~~
>> drivers/gpu/drm/drm_crtc_helper.c:589:2: error: implicit declaration of 
>> function 'drm_connector_list_iter_put' 
>> [-Werror=implicit-function-declaration]
 drm_connector_list_iter_put(_iter);
 ^~~
   drivers/gpu/drm/drm_crtc_helper.c:633:53: error: expected ';' before '{' 
token
 drm_for_each_connector_iter(connector, _iter) {
^
   drivers/gpu/drm/drm_crtc_helper.c:675:53: error: expected ';' before '{' 
token
 drm_for_each_connector_iter(connector, _iter) {
^
>> drivers/gpu/drm/drm_crtc_helper.c:767:3: error: expected ';' before 
>> 'connector'
  connector->encoder = save_connector_encoders[count++];
  ^
   drivers/gpu/drm/drm_crtc_helper.c:521:33: warning: unused variable 
'conn_iter' [-Wunused-variable]
 struct drm_connector_list_iter conn_iter;
^
   drivers/gpu/drm/drm_crtc_helper.c:517:49: warning: unused variable 
'new_encoder' [-Wunused-variable]
 struct drm_encoder **save_connector_encoders, *new_encoder, *encoder;
^~~
   drivers/gpu/drm/drm_crtc_helper.c:516:41: warning: unused variable 
'new_crtc' [-Wunused-variable]
 struct drm_crtc **save_encoder_crtcs, *new_crtc;
^~~~
   drivers/gpu/drm/drm_crtc_helper.c: In function 
'drm_helper_choose_encoder_dpms':
   drivers/gpu/drm/drm_crtc_helper.c:795:33: error: storage size of 'conn_iter' 
isn't known
 struct drm_connector_list_iter conn_iter;
^
   In file included from include/linux/linkage.h:4:0,
from include/linux/kernel.h:6,
from drivers/gpu/drm/drm_crtc_helper.c:32:
>> include/linux/compiler.h:149:2: error: expected ';' before 'if'
 if

Re: [Intel-gfx] [PATCH] drm: Convert all helpers to drm_connector_list_iter

2016-12-15 Thread kbuild test robot
Hi Daniel,

[auto build test ERROR on drm/drm-next]
[also build test ERROR on next-20161215]
[cannot apply to v4.9]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Daniel-Vetter/drm-Convert-all-helpers-to-drm_connector_list_iter/20161216-061508
base:   git://people.freedesktop.org/~airlied/linux.git drm-next
config: i386-randconfig-x005-201650 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=i386 

All errors (new ones prefixed by >>):

   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_helper_encoder_in_use':
   drivers/gpu/drm/drm_crtc_helper.c:91:33: error: storage size of 'conn_iter' 
isn't known
 struct drm_connector_list_iter conn_iter;
^
   drivers/gpu/drm/drm_crtc_helper.c:104:2: error: implicit declaration of 
function 'drm_connector_list_iter_get' [-Werror=implicit-function-declaration]
 drm_connector_list_iter_get(dev, _iter);
 ^~~
   drivers/gpu/drm/drm_crtc_helper.c:105:2: error: implicit declaration of 
function 'drm_for_each_connector_iter' [-Werror=implicit-function-declaration]
 drm_for_each_connector_iter(connector, _iter) {
 ^~~
   drivers/gpu/drm/drm_crtc_helper.c:105:53: error: expected ';' before '{' 
token
 drm_for_each_connector_iter(connector, _iter) {
^
   drivers/gpu/drm/drm_crtc_helper.c:91:33: warning: unused variable 
'conn_iter' [-Wunused-variable]
 struct drm_connector_list_iter conn_iter;
^
   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_crtc_helper_disable':
   drivers/gpu/drm/drm_crtc_helper.c:446:34: error: storage size of 'conn_iter' 
isn't known
  struct drm_connector_list_iter conn_iter;
 ^
   drivers/gpu/drm/drm_crtc_helper.c:452:54: error: expected ';' before '{' 
token
  drm_for_each_connector_iter(connector, _iter) {
 ^
   drivers/gpu/drm/drm_crtc_helper.c:446:34: warning: unused variable 
'conn_iter' [-Wunused-variable]
  struct drm_connector_list_iter conn_iter;
 ^
   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_crtc_helper_set_config':
   drivers/gpu/drm/drm_crtc_helper.c:521:33: error: storage size of 'conn_iter' 
isn't known
 struct drm_connector_list_iter conn_iter;
^
   drivers/gpu/drm/drm_crtc_helper.c:588:3: error: expected ';' before 
'save_connector_encoders'
  save_connector_encoders[count++] = connector->encoder;
  ^~~
   drivers/gpu/drm/drm_crtc_helper.c:589:2: error: implicit declaration of 
function 'drm_connector_list_iter_put' [-Werror=implicit-function-declaration]
 drm_connector_list_iter_put(_iter);
 ^~~
   drivers/gpu/drm/drm_crtc_helper.c:633:53: error: expected ';' before '{' 
token
 drm_for_each_connector_iter(connector, _iter) {
^
   drivers/gpu/drm/drm_crtc_helper.c:675:53: error: expected ';' before '{' 
token
 drm_for_each_connector_iter(connector, _iter) {
^
   drivers/gpu/drm/drm_crtc_helper.c:767:3: error: expected ';' before 
'connector'
  connector->encoder = save_connector_encoders[count++];
  ^
   drivers/gpu/drm/drm_crtc_helper.c:521:33: warning: unused variable 
'conn_iter' [-Wunused-variable]
 struct drm_connector_list_iter conn_iter;
^
   drivers/gpu/drm/drm_crtc_helper.c:517:49: warning: unused variable 
'new_encoder' [-Wunused-variable]
 struct drm_encoder **save_connector_encoders, *new_encoder, *encoder;
^~~
   drivers/gpu/drm/drm_crtc_helper.c:516:41: warning: unused variable 
'new_crtc' [-Wunused-variable]
 struct drm_crtc **save_encoder_crtcs, *new_crtc;
^~~~
   drivers/gpu/drm/drm_crtc_helper.c: In function 
'drm_helper_choose_encoder_dpms':
   drivers/gpu/drm/drm_crtc_helper.c:795:33: error: storage size of 'conn_iter' 
isn't known
 struct drm_connector_list_iter conn_iter;
^
>> drivers/gpu/drm/drm_crtc_helper.c:800:3: error: expected ';' before 'if'
  if (connector->encoder == encoder)
  ^~
   drivers/gpu/drm/drm_crtc_helper.c:795:33: warning: unused variable 
'conn_iter' [-Wunused-variable]
 struct drm_connector_list_iter conn_iter;
^
   drivers/gpu/drm/drm_crtc_helper.c: In function 'drm_he

Re: [Intel-gfx] [PATCH 8/8] drm/i915/get_params: Add HuC status to getparams

2016-12-15 Thread Chris Wilson
On Thu, Dec 15, 2016 at 02:29:50PM -0800, anushasr wrote:
> From: Peter Antoine 
> 
> This patch will allow for getparams to return the status of the HuC.
> As the HuC has to be validated by the GuC this patch uses the validated
> status to show when the HuC is loaded and ready for use. You cannot use
> the loaded status as with the GuC as the HuC is verified after it is
> loaded and is not usable until it is verified.
> 
> v2: removed the forewakes as the registers are already force-woken.
>  (T.Ursulin)
> v4: rebased.
> v5: rebased on top of drm-tip.
> v6: rebased. Removed any reference to intel_huc.h
> v7: rebased. Rename I915_PARAM_HAS_HUC to I915_PARAM_HUC_STATUS.
> Remove intel_is_huc_valid() since it is used only in one place.
> Put the case of I915_PARAM_HAS_HUC() in the right place.
> 
> Signed-off-by: Peter Antoine 
> Reviewed-by: Arkadiusz Hiler 
> ---
>  drivers/gpu/drm/i915/i915_drv.c | 4 
>  drivers/gpu/drm/i915/intel_huc_loader.c | 1 -
>  include/uapi/drm/i915_drm.h | 1 +
>  3 files changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 85a47c2..0bc016d 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -49,6 +49,7 @@
>  #include "i915_trace.h"
>  #include "i915_vgpu.h"
>  #include "intel_drv.h"
> +#include "intel_uc.h"
>  
>  static struct drm_driver driver;
>  
> @@ -315,6 +316,9 @@ static int i915_getparam(struct drm_device *dev, void 
> *data,
>   case I915_PARAM_MIN_EU_IN_POOL:
>   value = INTEL_INFO(dev_priv)->sseu.min_eu_in_pool;
>   break;
> + case I915_PARAM_HUC_STATUS:
> + value = I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED;

Same question as last time: does the device need to be awake? We know is
one of the GT power wells, so presumably we need an rpm_get/rpm_put as
well to access the register.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] Guc parameter Handling

2016-12-15 Thread Srivatsa, Anusha
Hi All,

I was wondering if we intend to keep -1 and 2 for the enable_guc_submission 
parameter. Since now we are gating guc loads if either guc_submission or 
enable_huc parameter is set, why have a -1(platform default) and 2(forcefully 
load) option? We anyway do not have any special default set per platform. For 
now the default is 0 on all platforms. Moving forward if GuC gets more stable 
and we want to set a default to a certain platform, we can add -1 then.

Also, why have a 2? We can use enable_guc_submission=1 in order to make sure 
the guc is loaded and guc_submission is enabled and set enable_guc_submission=0 
to make sure guc submission is not used.

Any thought on this?

Cheers,
Anusha

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 6/8] drm/i915/huc: Add debugfs for HuC loading status check

2016-12-15 Thread anushasr
From: Peter Antoine 

Add debugfs entry for HuC loading status check.

v2: rebase on-top of drm-intel-nightly.
v3: rebased again.
v7: rebased.
v8: rebased.
v9: rebased.
v10: rebased.
v11: rebased on top of drm-tip
v12: rebased.

Tested-by: Xiang Haihao 
Signed-off-by: Anusha Srivatsa 
Signed-off-by: Alex Dai 
Signed-off-by: Peter Antoine 
Reviewed-by: Dave Gordon 
Reviewed-by: Jeff McGee 
---
 drivers/gpu/drm/i915/i915_debugfs.c | 31 +++
 1 file changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 008afe6..2cdadbd 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2325,6 +2325,36 @@ static int i915_llc(struct seq_file *m, void *data)
return 0;
 }
 
+static int i915_huc_load_status_info(struct seq_file *m, void *data)
+{
+   struct drm_i915_private *dev_priv = node_to_i915(m->private);
+   struct intel_uc_fw *huc_fw = _priv->huc.fw;
+
+   if (!HAS_HUC_UCODE(dev_priv))
+   return 0;
+
+   seq_puts(m, "HuC firmware status:\n");
+   seq_printf(m, "\tpath: %s\n", huc_fw->uc_fw_path);
+   seq_printf(m, "\tfetch: %s\n",
+   intel_uc_fw_status_repr(huc_fw->fetch_status));
+   seq_printf(m, "\tload: %s\n",
+   intel_uc_fw_status_repr(huc_fw->load_status));
+   seq_printf(m, "\tversion wanted: %d.%d\n",
+   huc_fw->major_ver_wanted, huc_fw->minor_ver_wanted);
+   seq_printf(m, "\tversion found: %d.%d\n",
+   huc_fw->major_ver_found, huc_fw->minor_ver_found);
+   seq_printf(m, "\theader: offset is %d; size = %d\n",
+   huc_fw->header_offset, huc_fw->header_size);
+   seq_printf(m, "\tuCode: offset is %d; size = %d\n",
+   huc_fw->ucode_offset, huc_fw->ucode_size);
+   seq_printf(m, "\tRSA: offset is %d; size = %d\n",
+   huc_fw->rsa_offset, huc_fw->rsa_size);
+
+   seq_printf(m, "\nHuC status 0x%08x:\n", I915_READ(HUC_STATUS2));
+
+   return 0;
+}
+
 static int i915_guc_load_status_info(struct seq_file *m, void *data)
 {
struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -4553,6 +4583,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
{"i915_guc_info", i915_guc_info, 0},
{"i915_guc_load_status", i915_guc_load_status_info, 0},
{"i915_guc_log_dump", i915_guc_log_dump, 0},
+   {"i915_huc_load_status", i915_huc_load_status_info, 0},
{"i915_frequency_info", i915_frequency_info, 0},
{"i915_hangcheck_info", i915_hangcheck_info, 0},
{"i915_drpc_info", i915_drpc_info, 0},
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 8/8] drm/i915/get_params: Add HuC status to getparams

2016-12-15 Thread anushasr
From: Peter Antoine 

This patch will allow for getparams to return the status of the HuC.
As the HuC has to be validated by the GuC this patch uses the validated
status to show when the HuC is loaded and ready for use. You cannot use
the loaded status as with the GuC as the HuC is verified after it is
loaded and is not usable until it is verified.

v2: removed the forewakes as the registers are already force-woken.
 (T.Ursulin)
v4: rebased.
v5: rebased on top of drm-tip.
v6: rebased. Removed any reference to intel_huc.h
v7: rebased. Rename I915_PARAM_HAS_HUC to I915_PARAM_HUC_STATUS.
Remove intel_is_huc_valid() since it is used only in one place.
Put the case of I915_PARAM_HAS_HUC() in the right place.

Signed-off-by: Peter Antoine 
Reviewed-by: Arkadiusz Hiler 
---
 drivers/gpu/drm/i915/i915_drv.c | 4 
 drivers/gpu/drm/i915/intel_huc_loader.c | 1 -
 include/uapi/drm/i915_drm.h | 1 +
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 85a47c2..0bc016d 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -49,6 +49,7 @@
 #include "i915_trace.h"
 #include "i915_vgpu.h"
 #include "intel_drv.h"
+#include "intel_uc.h"
 
 static struct drm_driver driver;
 
@@ -315,6 +316,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
case I915_PARAM_MIN_EU_IN_POOL:
value = INTEL_INFO(dev_priv)->sseu.min_eu_in_pool;
break;
+   case I915_PARAM_HUC_STATUS:
+   value = I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED;
+   break;
case I915_PARAM_MMAP_GTT_VERSION:
/* Though we've started our numbering from 1, and so class all
 * earlier versions as 0, in effect their value is undefined as
diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c 
b/drivers/gpu/drm/i915/intel_huc_loader.c
index d8c5266..b06a613 100644
--- a/drivers/gpu/drm/i915/intel_huc_loader.c
+++ b/drivers/gpu/drm/i915/intel_huc_loader.c
@@ -288,4 +288,3 @@ void intel_huc_fini(struct drm_device *dev)
 
huc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
 }
-
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index da32c2f..57093b4 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -395,6 +395,7 @@ typedef struct drm_i915_irq_wait {
  * priorities and the driver will attempt to execute batches in priority order.
  */
 #define I915_PARAM_HAS_SCHEDULER41
+#define I915_PARAM_HUC_STATUS   42
 
 typedef struct drm_i915_getparam {
__s32 param;
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 4/8] drm/i915/huc: Add BXT HuC Loading Support

2016-12-15 Thread anushasr
From: Anusha Srivatsa 

This patch adds the HuC Loading for the BXT by using
the updated file construction.

Version 1.7 of the HuC firmware.

v2: rebased.
v3: rebased on top of drm-tip
v4: rebased.
v5: rebased. Rename BXT_FW_MAJOR to BXT_HUC_FW_

Cc: Jeff Mcgee 
Signed-off-by: Anusha Srivatsa 
Reviewed-by: Jeff McGee 
---
 drivers/gpu/drm/i915/intel_huc_loader.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c 
b/drivers/gpu/drm/i915/intel_huc_loader.c
index 0f929cc..f36efd4 100644
--- a/drivers/gpu/drm/i915/intel_huc_loader.c
+++ b/drivers/gpu/drm/i915/intel_huc_loader.c
@@ -40,6 +40,10 @@
  * Note that HuC firmware loading must be done before GuC loading.
  */
 
+#define BXT_HUC_FW_MAJOR 01
+#define BXT_HUC_FW_MINOR 07
+#define BXT_BLD_NUM 1398
+
 #define SKL_HUC_FW_MAJOR 01
 #define SKL_HUC_FW_MINOR 07
 #define SKL_BLD_NUM 1398
@@ -52,6 +56,9 @@
SKL_HUC_FW_MINOR, SKL_BLD_NUM)
 MODULE_FIRMWARE(I915_SKL_HUC_UCODE);
 
+#define I915_BXT_HUC_UCODE HUC_FW_PATH(bxt, BXT_HUC_FW_MAJOR, \
+   BXT_HUC_FW_MINOR, BXT_BLD_NUM)
+MODULE_FIRMWARE(I915_BXT_HUC_UCODE);
 /**
  * huc_ucode_xfer() - DMA's the firmware
  * @dev_priv: the drm device
@@ -157,6 +164,10 @@ void intel_huc_init(struct drm_i915_private *dev_priv)
fw_path = I915_SKL_HUC_UCODE;
huc_fw->major_ver_wanted = SKL_HUC_FW_MAJOR;
huc_fw->minor_ver_wanted = SKL_HUC_FW_MINOR;
+   } else if (IS_BROXTON(dev_priv)) {
+   fw_path = I915_BXT_HUC_UCODE;
+   huc_fw->major_ver_wanted = BXT_HUC_FW_MAJOR;
+   huc_fw->minor_ver_wanted = BXT_HUC_FW_MINOR;
}
 
huc_fw->uc_fw_path = fw_path;
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 7/8] drm/i915/huc: Support HuC authentication

2016-12-15 Thread anushasr
From: Peter Antoine 

The HuC authentication is done by host2guc call. The HuC RSA keys
are sent to GuC for authentication.

v2: rebased on top of drm-intel-nightly.
changed name format and upped version 1.7.
v3: rebased on top of drm-intel-nightly.
v4: changed wait_for_automic to wait_for
v5: rebased.
v7: rebased.
v8: rebased.
v9: rebased. Rename intel_huc_auh() to intel_guc_auth_huc()
and place the prototype in intel_guc.h,correct the comments.
v10: rebased.
v11: rebased.
v12: rebased on top of drm-tip
v13: rebased. Moved intel_guc_auth_huc from i915_guc_submission.c
to intel_uc.c.Update dev to dev_priv in intel_guc_auth_huc().
Renamed HOST2GUC_ACTION_AUTHENTICATE_HUC TO INTEL_GUC_ACTION_
AUTHENTICATE_HUC
v14: rebased.

Tested-by: Xiang Haihao 
Signed-off-by: Anusha Srivatsa 
Signed-off-by: Alex Dai 
Signed-off-by: Peter Antoine 
---
 drivers/gpu/drm/i915/intel_guc_fwif.h   |  1 +
 drivers/gpu/drm/i915/intel_guc_loader.c |  2 ++
 drivers/gpu/drm/i915/intel_uc.c | 62 +
 drivers/gpu/drm/i915/intel_uc.h |  1 +
 4 files changed, 66 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h 
b/drivers/gpu/drm/i915/intel_guc_fwif.h
index ed1ab40..ce4e05e 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -506,6 +506,7 @@ enum intel_guc_action {
INTEL_GUC_ACTION_EXIT_S_STATE = 0x502,
INTEL_GUC_ACTION_SLPC_REQUEST = 0x3003,
INTEL_GUC_ACTION_UK_LOG_ENABLE_LOGGING = 0x0E000,
+   INTEL_GUC_ACTION_AUTHENTICATE_HUC = 0x4000,
INTEL_GUC_ACTION_LIMIT
 };
 
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c 
b/drivers/gpu/drm/i915/intel_guc_loader.c
index 2257495..7605f36 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -529,6 +529,8 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
intel_uc_fw_status_repr(guc_fw->fetch_status),
intel_uc_fw_status_repr(guc_fw->load_status));
 
+   intel_guc_auth_huc(dev_priv);
+
if (i915.enable_guc_submission) {
if (i915.guc_log_level >= 0)
gen9_enable_guc_interrupts(dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c
index 8ae6795..b90ac57 100644
--- a/drivers/gpu/drm/i915/intel_uc.c
+++ b/drivers/gpu/drm/i915/intel_uc.c
@@ -138,3 +138,65 @@ int intel_guc_log_control(struct intel_guc *guc, u32 
control_val)
 
return intel_guc_send(guc, action, ARRAY_SIZE(action));
 }
+
+/**
+ * intel_guc_auth_huc() - authenticate ucode
+ * @dev_priv: the drm_i915_device
+ *
+ * Triggers a HuC fw authentication request to the GuC via intel_guc_action_
+ * authenticate_huc interface.
+ * interface.
+ */
+void intel_guc_auth_huc(struct drm_i915_private *dev_priv)
+{
+   struct intel_guc *guc = _priv->guc;
+   struct intel_huc *huc = _priv->huc;
+   struct i915_vma *vma;
+   int ret;
+   u32 data[2];
+
+   /* Bypass the case where there is no HuC firmware */
+   if (huc->fw.fetch_status == INTEL_UC_FIRMWARE_NONE ||
+   huc->fw.load_status == INTEL_UC_FIRMWARE_NONE)
+   return;
+
+   if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) {
+   DRM_ERROR("HuC: GuC fw wasn't loaded. Can't authenticate");
+   return;
+   }
+
+   if (huc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) {
+   DRM_ERROR("HuC: fw wasn't loaded. Nothing to authenticate");
+   return;
+   }
+
+   vma = i915_gem_object_ggtt_pin(huc->fw.uc_fw_obj, NULL, 0, 0, 0);
+   if (IS_ERR(vma)) {
+   DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma));
+   return;
+   }
+
+
+   /* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
+   I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
+
+   /* Specify auth action and where public signature is. */
+   data[0] = INTEL_GUC_ACTION_AUTHENTICATE_HUC;
+   data[1] = i915_ggtt_offset(vma) + huc->fw.rsa_offset;
+
+   ret = intel_guc_send(guc, data, ARRAY_SIZE(data));
+   if (ret) {
+   DRM_ERROR("HuC: GuC did not ack Auth request\n");
+   goto out;
+   }
+
+   /* Check authentication status, it should be done by now */
+   ret = wait_for((I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED) > 0, 50);
+   if (ret) {
+   DRM_ERROR("HuC: Authentication failed\n");
+   goto out;
+   }
+
+out:
+   i915_vma_unpin(vma);
+}
diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
index 57aef56..e69d47c 100644
--- a/drivers/gpu/drm/i915/intel_uc.h
+++ b/drivers/gpu/drm/i915/intel_uc.h
@@ -192,6 +192,7 @@ int intel_guc_sample_forcewake(struct intel_guc *guc);
 int intel_guc_log_flush_complete(struct 

[Intel-gfx] [PATCH 0/8] HuC Loading Patches

2016-12-15 Thread anushasr
These patches add HuC loading support. The driver builds a frame level
workload which is stored in the graphics memory. This workload is presented
to HuC for processing. The driver, therefore should first determine if the
HuC is enabled and also read the huC athentication status bit to determine
if HuC was successfully loaded. The GuC is required to authenticate the HuC.
The userspace patches that check for a fully loaded HuC firmware and use it
can be found at:

https://lists.freedesktop.org/archives/libva/2016-September/004554.html
https://lists.freedesktop.org/archives/libva/2016-September/004555.html
 
More information regarding the HuC, batch commands that configure the 
HuC etc can be found at-
https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-skl-vol02a-commandreference-instructions-huc.pdf
https://www.x.org/docs/intel/CHV/intel-gfx-prm-osrc-chv-bsw-vol10-hevc.pdf

v2: rebased.
v3: rebased. Changed the code following the review comments.
v4: Added action_lock initialization fix provided by Arek
(Hiler Arkadiusz) to the first patch in the series- Make the
GuC fw loading helper functions general. 
v5: rebased on top of drm-tip. The patch series is now in sync with GuC 
code reorganization efforts by Arek-
https://patchwork.freedesktop.org/series/15896/
v6:rebased. Organize code. Move contents of intel_huc.h to intel_uc.h.
Update function intel_huc_load(),intel_huc_init() and intel_uc_fw_fetch()
to accept dev_priv instead of dev.
v7: rebased. Remove intel_is_huc_valid() since it is called onoly once.
Refactor the code to reduce redundency. Remove fiels like uc_dev which
are no longer used.

Signed-off-by: Anusha Srivatsa 
Cc: Arek 
Cc: Jeff Mcgee  BLURB HERE ***
Cc: Chris Wilson 

Anusha Srivatsa (3):
  drm/i915/huc: Add HuC fw loading support
  drm/i915/huc: Add BXT HuC Loading Support
  drm/i915/HuC: Add KBL huC loading Support

Peter Antoine (5):
  drm/i915/guc: Make the GuC fw loading helper functions general
  drm/i915/huc: Unified css_header struct for GuC and HuC
  drm/i915/huc: Add debugfs for HuC loading status check
  drm/i915/huc: Support HuC authentication
  drm/i915/get_params: Add HuC status to getparams

 drivers/gpu/drm/i915/Makefile  |   1 +
 drivers/gpu/drm/i915/i915_debugfs.c|  43 -
 drivers/gpu/drm/i915/i915_drv.c|   8 +-
 drivers/gpu/drm/i915/i915_drv.h|   3 +-
 drivers/gpu/drm/i915/i915_guc_reg.h|   3 +
 drivers/gpu/drm/i915/i915_guc_submission.c |   4 +-
 drivers/gpu/drm/i915/intel_guc_fwif.h  |  24 ++-
 drivers/gpu/drm/i915/intel_guc_loader.c| 201 +++-
 drivers/gpu/drm/i915/intel_huc_loader.c| 290 +
 drivers/gpu/drm/i915/intel_uc.c|  62 ++
 drivers/gpu/drm/i915/intel_uc.h|  63 +--
 include/uapi/drm/i915_drm.h|   1 +
 12 files changed, 579 insertions(+), 124 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_huc_loader.c

-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 5/8] drm/i915/HuC: Add KBL huC loading Support

2016-12-15 Thread anushasr
From: Anusha Srivatsa 

This patch adds the support to load HuC on KBL
Version 2.0

v2: rebased.
v3: rebased on top of drm-tip
v4: rebased.
v5: rebased. Rename KBL_FW_ to KBL_HUC_FW_

Cc: Jeff Mcgee 
Signed-off-by: Anusha Srivatsa 
Reviewed-by: Jeff McGee 
---
 drivers/gpu/drm/i915/intel_huc_loader.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c 
b/drivers/gpu/drm/i915/intel_huc_loader.c
index f36efd4..d8c5266 100644
--- a/drivers/gpu/drm/i915/intel_huc_loader.c
+++ b/drivers/gpu/drm/i915/intel_huc_loader.c
@@ -48,6 +48,10 @@
 #define SKL_HUC_FW_MINOR 07
 #define SKL_BLD_NUM 1398
 
+#define KBL_HUC_FW_MAJOR 02
+#define KBL_HUC_FW_MINOR 00
+#define KBL_BLD_NUM 1810
+
 #define HUC_FW_PATH(platform, major, minor, bld_num) \
"i915/" __stringify(platform) "_huc_ver" __stringify(major) "_" \
__stringify(minor) "_" __stringify(bld_num) ".bin"
@@ -59,6 +63,11 @@ MODULE_FIRMWARE(I915_SKL_HUC_UCODE);
 #define I915_BXT_HUC_UCODE HUC_FW_PATH(bxt, BXT_HUC_FW_MAJOR, \
BXT_HUC_FW_MINOR, BXT_BLD_NUM)
 MODULE_FIRMWARE(I915_BXT_HUC_UCODE);
+
+#define I915_KBL_HUC_UCODE HUC_FW_PATH(kbl, KBL_HUC_FW_MAJOR, \
+   KBL_HUC_FW_MINOR, KBL_BLD_NUM)
+MODULE_FIRMWARE(I915_KBL_HUC_UCODE);
+
 /**
  * huc_ucode_xfer() - DMA's the firmware
  * @dev_priv: the drm device
@@ -168,8 +177,15 @@ void intel_huc_init(struct drm_i915_private *dev_priv)
fw_path = I915_BXT_HUC_UCODE;
huc_fw->major_ver_wanted = BXT_HUC_FW_MAJOR;
huc_fw->minor_ver_wanted = BXT_HUC_FW_MINOR;
+   } else if (IS_KABYLAKE(dev_priv)) {
+   fw_path = I915_KBL_HUC_UCODE;
+   huc_fw->major_ver_wanted = KBL_HUC_FW_MAJOR;
+   huc_fw->minor_ver_wanted = KBL_HUC_FW_MINOR;
}
 
+   if (fw_path == NULL)
+   return;
+
huc_fw->uc_fw_path = fw_path;
huc_fw->fetch_status = INTEL_UC_FIRMWARE_PENDING;
 
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 3/8] drm/i915/huc: Add HuC fw loading support

2016-12-15 Thread anushasr
From: Anusha Srivatsa 

The HuC loading process is similar to GuC. The intel_uc_fw_fetch()
is used for both cases.

HuC loading needs to be before GuC loading. The WOPCM setting must
be done early before loading any of them.

v2: rebased on-top of drm-intel-nightly.
removed if(HAS_GUC()) before the guc call. (D.Gordon)
update huc_version number of format.
v3: rebased to drm-intel-nightly, changed the file name format to
match the one in the huc package.
Changed dev->dev_private to to_i915()
v4: moved function back to where it was.
change wait_for_atomic to wait_for.
v5: rebased + comment changes.
v7: rebased.
v8: rebased.
v9: rebased. Changed the year in the copyright message to reflect
the right year.Correct the comments,remove the unwanted WARN message,
replace drm_gem_object_unreference() with i915_gem_object_put().Make the
prototypes in intel_huc.h non-extern.
v10: rebased. Update the file construction done by HuC. It is similar to
GuC.Adopted the approach used in-
https://patchwork.freedesktop.org/patch/104355/ 
v11: Fix warnings remove old declaration
v12: Change dev to dev_priv in macro definition.
Corrected comments.
v13: rebased.
v14: rebased on top of drm-tip
v15: rebased. Updated functions intel_huc_load(),intel_huc_init() and
intel_uc_fw_fetch() to accept dev_priv instead of dev. Moved contents
of intel_huc.h to intel_uc.h
v16: change SKL_FW_ to SKL_HUC_FW_. Add intel_ prefix to guc_wopcm_size().
Remove unwanted checks in intel_uc.h. Rename huc_fw in struct intel_huc to
simply fw to avoid redundency.

Cc: Tvrtko Ursulin 
Tested-by: Xiang Haihao 
Signed-off-by: Anusha Srivatsa 
Signed-off-by: Alex Dai 
Signed-off-by: Peter Antoine 
---
 drivers/gpu/drm/i915/Makefile   |   1 +
 drivers/gpu/drm/i915/i915_drv.c |   4 +-
 drivers/gpu/drm/i915/i915_drv.h |   3 +-
 drivers/gpu/drm/i915/i915_guc_reg.h |   3 +
 drivers/gpu/drm/i915/intel_guc_loader.c |  11 +-
 drivers/gpu/drm/i915/intel_huc_loader.c | 264 
 drivers/gpu/drm/i915/intel_uc.h |  18 +++
 7 files changed, 297 insertions(+), 7 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_huc_loader.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 5196509..45ae124 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -57,6 +57,7 @@ i915-y += i915_cmd_parser.o \
 # general-purpose microcontroller (GuC) support
 i915-y += intel_uc.o \
  intel_guc_loader.o \
+ intel_huc_loader.o \
  i915_guc_submission.o
 
 # autogenerated null render state
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 6428588..85a47c2 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -600,6 +600,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
if (ret)
goto cleanup_irq;
 
+   intel_huc_init(dev_priv);
intel_guc_init(dev_priv);
 
ret = i915_gem_init(dev_priv);
@@ -627,6 +628,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
DRM_ERROR("failed to idle hardware; continuing to unload!\n");
i915_gem_fini(dev_priv);
 cleanup_irq:
+   intel_huc_fini(dev);
intel_guc_fini(dev_priv);
drm_irq_uninstall(dev);
intel_teardown_gmbus(dev_priv);
@@ -1313,7 +1315,7 @@ void i915_driver_unload(struct drm_device *dev)
 
/* Flush any outstanding unpin_work. */
drain_workqueue(dev_priv->wq);
-
+   intel_huc_fini(dev);
intel_guc_fini(dev_priv);
i915_gem_fini(dev_priv);
intel_fbc_cleanup_cfb(dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4199d26..bd5f235 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2134,6 +2134,7 @@ struct drm_i915_private {
 
struct intel_gvt *gvt;
 
+   struct intel_huc huc;
struct intel_guc guc;
 
struct intel_csr csr;
@@ -2908,7 +2909,7 @@ intel_info(const struct drm_i915_private *dev_priv)
 #define HAS_GUC(dev_priv)  ((dev_priv)->info.has_guc)
 #define HAS_GUC_UCODE(dev_priv)(HAS_GUC(dev_priv))
 #define HAS_GUC_SCHED(dev_priv)(HAS_GUC(dev_priv))
-
+#define HAS_HUC_UCODE(dev_priv)(HAS_GUC(dev_priv))
 #define HAS_RESOURCE_STREAMER(dev_priv) 
((dev_priv)->info.has_resource_streamer)
 
 #define HAS_POOLED_EU(dev_priv)((dev_priv)->info.has_pooled_eu)
diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h 
b/drivers/gpu/drm/i915/i915_guc_reg.h
index 5e638fc..f9829f6 100644
--- a/drivers/gpu/drm/i915/i915_guc_reg.h
+++ b/drivers/gpu/drm/i915/i915_guc_reg.h
@@ -61,9 +61,12 @@
 #define   DMA_ADDRESS_SPACE_GTT  (8 << 16)
 #define DMA_COPY_SIZE  _MMIO(0xc310)
 

[Intel-gfx] [PATCH 1/8] drm/i915/guc: Make the GuC fw loading helper functions general

2016-12-15 Thread anushasr
From: Peter Antoine 

Rename some of the GuC fw loading code to make them more general. We
will utilise them for HuC loading as well.
 s/intel_guc_fw/intel_uc_fw/g
 s/GUC_FIRMWARE/UC_FIRMWARE/g

Struct intel_guc_fw is renamed to intel_uc_fw. Prefix of tts members,
such as 'guc' or 'guc_fw' either is renamed to 'uc' or removed for
same purpose.

v2: rebased on top of nightly.
reapplied the search/replace as upstream code as changed.
v3: rebased again on drm-nightly.
v4: removed G from messages in shared fw fetch function.
v5: rebased.
v7: rebased.
v8: rebased.
v9: rebased.
v10: rebased.
v11: rebased.
v12: rebased on top of drm-tip
v13: rebased.Updated dev to dev_priv in intel_guc_setup(), guc_fw_getch()
and intel_guc_init().
v14: rebased. Remove uint32_t fw_type to patch 2. Add INTEL_ prefix for
fields in enum intel_uc_fw_status. Remove uc_dev field since its never
used.Rename uc_fw to just fw and guc_fw to fw to avoid redundency.

Signed-off-by: Anusha Srivatsa 
Signed-off-by: Alex Dai 
Signed-off-by: Peter Antoine 
---
 drivers/gpu/drm/i915/i915_debugfs.c|  12 +--
 drivers/gpu/drm/i915/i915_guc_submission.c |   4 +-
 drivers/gpu/drm/i915/intel_guc_loader.c| 157 +++--
 drivers/gpu/drm/i915/intel_uc.h|  36 +++
 4 files changed, 105 insertions(+), 104 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 15deb2b..008afe6 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2328,7 +2328,7 @@ static int i915_llc(struct seq_file *m, void *data)
 static int i915_guc_load_status_info(struct seq_file *m, void *data)
 {
struct drm_i915_private *dev_priv = node_to_i915(m->private);
-   struct intel_guc_fw *guc_fw = _priv->guc.guc_fw;
+   struct intel_uc_fw *guc_fw = _priv->guc.fw;
u32 tmp, i;
 
if (!HAS_GUC_UCODE(dev_priv))
@@ -2336,15 +2336,15 @@ static int i915_guc_load_status_info(struct seq_file 
*m, void *data)
 
seq_printf(m, "GuC firmware status:\n");
seq_printf(m, "\tpath: %s\n",
-   guc_fw->guc_fw_path);
+   guc_fw->uc_fw_path);
seq_printf(m, "\tfetch: %s\n",
-   intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status));
+   intel_uc_fw_status_repr(guc_fw->fetch_status));
seq_printf(m, "\tload: %s\n",
-   intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
+   intel_uc_fw_status_repr(guc_fw->load_status));
seq_printf(m, "\tversion wanted: %d.%d\n",
-   guc_fw->guc_fw_major_wanted, guc_fw->guc_fw_minor_wanted);
+   guc_fw->major_ver_wanted, guc_fw->minor_ver_wanted);
seq_printf(m, "\tversion found: %d.%d\n",
-   guc_fw->guc_fw_major_found, guc_fw->guc_fw_minor_found);
+   guc_fw->major_ver_found, guc_fw->minor_ver_found);
seq_printf(m, "\theader: offset is %d; size = %d\n",
guc_fw->header_offset, guc_fw->header_size);
seq_printf(m, "\tuCode: offset is %d; size = %d\n",
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c 
b/drivers/gpu/drm/i915/i915_guc_submission.c
index 7fa4e74..b8ad8ff 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -1493,7 +1493,7 @@ int intel_guc_suspend(struct drm_i915_private *dev_priv)
struct i915_gem_context *ctx;
u32 data[3];
 
-   if (guc->guc_fw.guc_fw_load_status != GUC_FIRMWARE_SUCCESS)
+   if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
return 0;
 
gen9_disable_guc_interrupts(dev_priv);
@@ -1520,7 +1520,7 @@ int intel_guc_resume(struct drm_i915_private *dev_priv)
struct i915_gem_context *ctx;
u32 data[3];
 
-   if (guc->guc_fw.guc_fw_load_status != GUC_FIRMWARE_SUCCESS)
+   if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
return 0;
 
if (i915.guc_log_level >= 0)
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c 
b/drivers/gpu/drm/i915/intel_guc_loader.c
index 21db697..9b3dbea 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -81,16 +81,16 @@ MODULE_FIRMWARE(I915_BXT_GUC_UCODE);
 MODULE_FIRMWARE(I915_KBL_GUC_UCODE);
 
 /* User-friendly representation of an enum */
-const char *intel_guc_fw_status_repr(enum intel_guc_fw_status status)
+const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status)
 {
switch (status) {
-   case GUC_FIRMWARE_FAIL:
+   case INTEL_UC_FIRMWARE_FAIL:
return "FAIL";
-   case GUC_FIRMWARE_NONE:
+   case INTEL_UC_FIRMWARE_NONE:
return "NONE";
-   case GUC_FIRMWARE_PENDING:
+   case INTEL_UC_FIRMWARE_PENDING:
return "PENDING";
-   case GUC_FIRMWARE_SUCCESS:
+   

[Intel-gfx] [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC

2016-12-15 Thread anushasr
From: Peter Antoine 

HuC firmware css header has almost exactly same definition as GuC
firmware except for the sw_version. Also, add a new member fw_type
into intel_uc_fw to indicate what kind of fw it is. So, the loader
will pull right sw_version from header.

v2: rebased on-top of drm-intel-nightly
v3: rebased on-top of drm-intel-nightly (again).
v4: rebased + spaces.
v7: rebased.
v8: rebased.
v9: rebased. Rename device_id to guc_branch_client_version,
make guc_sw_version a union. . Put UC_FW_TYPE_GUC
and UC_FW_TYPE_HUC into an enum.
v10: rebased.
v11: rebased.
v12: rebased on top of drm-tip.
v13: rebased.Update dev to dev_priv in intel_uc_fw_fetch
v14: rebased. Add INTEL_ prefix to an enum. Add fw_type declaration
from patch 1.Combine two different unions for huc and guc version,
reserved etc into one union with two structs.

Tested-by: Xiang Haihao 
Signed-off-by: Anusha Srivatsa 
Signed-off-by: Alex Dai 
Signed-off-by: Peter Antoine 
---
 drivers/gpu/drm/i915/intel_guc_fwif.h   | 23 ++
 drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++---
 drivers/gpu/drm/i915/intel_uc.h |  6 +
 3 files changed, 53 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h 
b/drivers/gpu/drm/i915/intel_guc_fwif.h
index 3202b32..ed1ab40 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -145,7 +145,7 @@
  * The GuC firmware layout looks like this:
  *
  * +---+
- * |guc_css_header |
+ * | uc_css_header |
  * |   |
  * | contains major/minor version  |
  * +---+
@@ -172,9 +172,16 @@
  * 3. Length info of each component can be found in header, in dwords.
  * 4. Modulus and exponent key are not required by driver. They may not appear
  *in fw. So driver will load a truncated firmware in this case.
+ *
+ * HuC firmware layout is same as GuC firmware.
+ *
+ * HuC firmware css header is different. However, the only difference is where
+ * the version information is saved. The uc_css_header is unified to support
+ * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
+ * uc_css_header.guc_sw_version for GuC.
  */
 
-struct guc_css_header {
+struct uc_css_header {
uint32_t module_type;
/* header_size includes all non-uCode bits, including css_header, rsa
 * key, modulus key and exponent data. */
@@ -205,8 +212,16 @@ struct guc_css_header {
 
char username[8];
char buildnumber[12];
-   uint32_t device_id;
-   uint32_t guc_sw_version;
+   union {
+   struct {
+   uint32_t branch_client_version;
+   uint32_t sw_version;
+   } guc;
+   struct {
+   uint32_t sw_version;
+   uint32_t reserved;
+   } huc;
+   };
uint32_t prod_preprod_fw;
uint32_t reserved[12];
uint32_t header_info;
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c 
b/drivers/gpu/drm/i915/intel_guc_loader.c
index 9b3dbea..09e463b 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -593,7 +593,7 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
struct pci_dev *pdev = dev_priv->drm.pdev;
struct drm_i915_gem_object *obj;
const struct firmware *fw = NULL;
-   struct guc_css_header *css;
+   struct uc_css_header *css;
size_t size;
int err;
 
@@ -610,19 +610,19 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
uc_fw->uc_fw_path, fw);
 
/* Check the size of the blob before examining buffer contents */
-   if (fw->size < sizeof(struct guc_css_header)) {
+   if (fw->size < sizeof(struct uc_css_header)) {
DRM_NOTE("Firmware header is missing\n");
goto fail;
}
 
-   css = (struct guc_css_header *)fw->data;
+   css = (struct uc_css_header *)fw->data;
 
/* Firmware bits always start from header */
uc_fw->header_offset = 0;
uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
 
-   if (uc_fw->header_size != sizeof(struct guc_css_header)) {
+   if (uc_fw->header_size != sizeof(struct uc_css_header)) {
DRM_NOTE("CSS header definition mismatch\n");
goto fail;
}
@@ -646,21 +646,36 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
goto fail;
}
 
-   /* Header and uCode will be loaded to WOPCM. Size of the two. */
-   size = uc_fw->header_size + uc_fw->ucode_size;
-   if (size > 

Re: [Intel-gfx] [PATCH 3/5] drm/i915/guc: Simplify intel_guc_load()

2016-12-15 Thread Daniele Ceraolo Spurio



On 15/12/16 07:47, Arkadiusz Hiler wrote:

Current version of intel_guc_load() does a lot:
 - cares about submission
 - loads huc
 - implement WA

This change offloads some of the logic to intel_uc_load(), which now
cares about the above.

Cc: Anusha Srivatsa 
Cc: Jeff McGee 
Cc: Michal Winiarski 
Signed-off-by: Arkadiusz Hiler 
---
 drivers/gpu/drm/i915/i915_gem.c |   2 +-
 drivers/gpu/drm/i915/intel_guc_loader.c | 126 +---
 drivers/gpu/drm/i915/intel_uc.c |  83 +
 drivers/gpu/drm/i915/intel_uc.h |   8 ++
 4 files changed, 110 insertions(+), 109 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 6af4e85..76b52c6 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4412,7 +4412,7 @@ i915_gem_init_hw(struct drm_i915_private *dev_priv)
intel_mocs_init_l3cc_table(dev_priv);

/* We can't enable contexts until all firmware is loaded */
-   ret = intel_guc_load(dev_priv);
+   ret = intel_uc_load(dev_priv);
if (ret)
goto out;

diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c 
b/drivers/gpu/drm/i915/intel_guc_loader.c
index f8b28b1..b76b556 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -97,7 +97,7 @@ const char *intel_guc_fw_status_repr(enum intel_guc_fw_status 
status)
}
 };

-static void guc_interrupts_release(struct drm_i915_private *dev_priv)
+void guc_interrupts_release(struct drm_i915_private *dev_priv)
 {
struct intel_engine_cs *engine;
enum intel_engine_id id;
@@ -115,7 +115,7 @@ static void guc_interrupts_release(struct drm_i915_private 
*dev_priv)
I915_WRITE(GUC_WD_VECS_IER, 0);
 }

-static void guc_interrupts_capture(struct drm_i915_private *dev_priv)
+void guc_interrupts_capture(struct drm_i915_private *dev_priv)
 {
struct intel_engine_cs *engine;
enum intel_engine_id id;
@@ -334,7 +334,7 @@ static int guc_ucode_xfer_dma(struct drm_i915_private 
*dev_priv,
return ret;
 }

-static u32 guc_wopcm_size(struct drm_i915_private *dev_priv)
+u32 guc_wopcm_size(struct drm_i915_private *dev_priv)
 {
u32 wopcm_size = GUC_WOPCM_TOP;

@@ -417,7 +417,7 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
return ret;
 }

-static int guc_hw_reset(struct drm_i915_private *dev_priv)
+int guc_hw_reset(struct drm_i915_private *dev_priv)


If I haven't missed anything, guc_hw_reset is only called in 1 place, so 
we could keep the function static and move it to intel_uc.c.



 {
int ret;
u32 guc_status;
@@ -452,75 +452,37 @@ int intel_guc_load(struct drm_i915_private *dev_priv)
 {
struct intel_guc_fw *guc_fw = _priv->guc.guc_fw;
const char *fw_path = guc_fw->guc_fw_path;
-   int retries, ret, err;
+   int ret;

DRM_DEBUG_DRIVER("GuC fw status: path %s, fetch %s, load %s\n",
fw_path,
intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status),
intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));

-   /* Loading forbidden, or no firmware to load? */
-   if (!i915.enable_guc_loading) {
-   err = 0;
-   goto fail;
-   } else if (fw_path == NULL) {
+   if (fw_path == NULL) {
/* Device is known to have no uCode (e.g. no GuC) */
-   err = -ENXIO;
-   goto fail;
+   return -ENXIO;
} else if (*fw_path == '\0') {
/* Device has a GuC but we don't know what f/w to load? */
WARN(1, "No GuC firmware known for this platform!\n");
-   err = -ENODEV;
-   goto fail;
+   return -ENODEV;
}

/* Fetch failed, or already fetched but failed to load? */
if (guc_fw->guc_fw_fetch_status != GUC_FIRMWARE_SUCCESS) {
-   err = -EIO;
-   goto fail;
+   return -EIO;
} else if (guc_fw->guc_fw_load_status == GUC_FIRMWARE_FAIL) {
-   err = -ENOEXEC;
-   goto fail;
+   return -ENOEXEC;
}

-   guc_interrupts_release(dev_priv);
-   gen9_reset_guc_interrupts(dev_priv);
-
guc_fw->guc_fw_load_status = GUC_FIRMWARE_PENDING;

-   DRM_DEBUG_DRIVER("GuC fw status: fetch %s, load %s\n",
-   intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status),
-   intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
-
-   err = i915_guc_submission_init(dev_priv);
-   if (err)
-   goto fail;
-
-   /*
-* WaEnableuKernelHeaderValidFix:skl,bxt
-* For BXT, this is only upto B0 but below WA is required for later
-* steppings also so this is extended as well.
-*/


This comment is 

Re: [Intel-gfx] [alsa-devel] [PATCH 3/7] ALSA: add shell for Intel HDMI LPE audio driver

2016-12-15 Thread Takashi Iwai
On Thu, 15 Dec 2016 21:37:03 +0100,
Pierre-Louis Bossart wrote:
> 
> 
> >>> Subject: Re: [PATCH 3/7] ALSA: add shell for Intel HDMI LPE audio driver
> 
> >>> Why do we need a "shell" and indirect calls?
> >>> This is a small driver set, so it's not utterly unacceptable, but it 
> >>> still makes
> >>> things a bit more complicated than necessary, so I'd like to understand 
> >>> the
> >>> idea behind it.
> 
> The 'shell' comes from an early prototype which didn't do much except
> create the device. The title of the commit should be changed if it
> threw you off.
> 
> >> This solution does not use component interface to talk between
> >> Audio and i915 driver. The reason for that is the HDMI audio device is 
> >> created
> >> by i915 driver with only one callback pointer passed as pdata. Unlike HDA, 
> >> the HDMI audio
> >> driver does not get loaded if the i915 does not create child device.
> >> Since there is only one callback needed we are not using the component
> >> interface to make things simpler.
> >> This design was co-worked with i915 folks to makes interaction simpler.
> >
> > The interaction between i915 and audio is simple, yes, it just exposes
> > a few things, mmio ptr, irq, etc.  But still I don't understand why
> > multiple layers of indirect accesses are needed *inside* lpe audio
> > driver itself.  For example, suspend/resume action is cascaded to yet
> > another ops.
> >
> > I would understand if this "shell" provides a few thin accessors to
> > the raw i915 registers.  But another layering over a single driver
> > implementation makes little sense in regard of abstraction.  (If there
> > were multiple class inherits, it's a different story, of course.)
> 
> No disagreement here Takashi.
> I was planning to remove this abstraction in a second incremental pass
> that would only be on the audio side, for now keeping this layer would
> allow me to add the DisplayPort changes faster. If we simplify this
> now then I will have so many differences with the legacy code it'll be
> a nightmare. I have no emotional attachment to the legacy but it's
> just pragmatic to avoid changing everything at once.
> 
> As you also mentioned it, this second pass could also reuse all the
> ELD parsing that is still duplicated. These HDMI patches are not a
> single-shot contribution, you'll have updates coming your way.

OK, if the current structure helps for DP support, it's no problem to
keep it.  We can refactor the code later easily, too -- it's a single
driver code, after all.


thanks,

Takashi
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [bug report] drm/i915: Small compaction of the engine init code

2016-12-15 Thread Chris Wilson
On Thu, Dec 15, 2016 at 11:44:13PM +0300, Dan Carpenter wrote:
> Hello Tvrtko Ursulin,
> 
> The patch a19d6ff29a82: "drm/i915: Small compaction of the engine
> init code" from Jun 23, 2016, leads to the following static checker
> warning:
> 
>   drivers/gpu/drm/i915/intel_lrc.c:1973 logical_render_ring_init()
>   warn: passing freed memory 'engine'
> 
> drivers/gpu/drm/i915/intel_lrc.c
>   1970  
>   1971  ret = logical_ring_init(engine);
>   1972  if (ret) {
>   1973  lrc_destroy_wa_ctx_obj(engine);
> 
> The problem is that logical_ring_init() frees "engine" on the error
> path so this is a use after free.

And calls lrc_destroy_wa_ctx_obj() in the process. So we can

diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 067394b0a769..1c1bad8ae7b0 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1940,12 +1940,7 @@ int logical_render_ring_init(struct intel_engine_cs 
*engine)
  ret);
}
 
-   ret = logical_ring_init(engine);
-   if (ret) {
-   lrc_destroy_wa_ctx_obj(engine);
-   }
-
-   return ret;
+   return logical_ring_init(engine);
 }
 
 int logical_xcs_ring_init(struct intel_engine_cs *engine)

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [bug report] drm/i915: Small compaction of the engine init code

2016-12-15 Thread Dan Carpenter
Hello Tvrtko Ursulin,

The patch a19d6ff29a82: "drm/i915: Small compaction of the engine
init code" from Jun 23, 2016, leads to the following static checker
warning:

drivers/gpu/drm/i915/intel_lrc.c:1973 logical_render_ring_init()
warn: passing freed memory 'engine'

drivers/gpu/drm/i915/intel_lrc.c
  1970  
  1971  ret = logical_ring_init(engine);
  1972  if (ret) {
  1973  lrc_destroy_wa_ctx_obj(engine);

The problem is that logical_ring_init() frees "engine" on the error
path so this is a use after free.

  1974  }
  1975  
  1976  return ret;
  1977  }

regards,
dan carpenter
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [alsa-devel] [PATCH 7/7] ALSA: x86: hdmi: continue playback even when display resolution changes

2016-12-15 Thread Pierre-Louis Bossart



This change itself is OK, but this made me wonder about the driver
implementation: the current MAX_PB=1 is the hardware limitation or the
soft limitation?  That is, can't we play back two streams when we connect
two HDMI monitors?



Two streams was never validated from hardware per se. So setting the limitation 
in software.


To be clearer, the IP itself does support 2 streams going to two 
different pipes in parallel but we never had a validation platform for 
Atom gizmos with two connectors and no use case for tablets/phone.
Never say never as usual, now we see CHT mini-PC devices with 2 
connectors, either both DP or DP+HDMI so we'll have to see how things go 
when both are enabled. It's on the TODO list.


___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [alsa-devel] [PATCH 3/7] ALSA: add shell for Intel HDMI LPE audio driver

2016-12-15 Thread Pierre-Louis Bossart



Subject: Re: [PATCH 3/7] ALSA: add shell for Intel HDMI LPE audio driver



Why do we need a "shell" and indirect calls?
This is a small driver set, so it's not utterly unacceptable, but it still makes
things a bit more complicated than necessary, so I'd like to understand the
idea behind it.


The 'shell' comes from an early prototype which didn't do much except 
create the device. The title of the commit should be changed if it threw 
you off.



This solution does not use component interface to talk between
Audio and i915 driver. The reason for that is the HDMI audio device is created
by i915 driver with only one callback pointer passed as pdata. Unlike HDA, the 
HDMI audio
driver does not get loaded if the i915 does not create child device.
Since there is only one callback needed we are not using the component
interface to make things simpler.
This design was co-worked with i915 folks to makes interaction simpler.


The interaction between i915 and audio is simple, yes, it just exposes
a few things, mmio ptr, irq, etc.  But still I don't understand why
multiple layers of indirect accesses are needed *inside* lpe audio
driver itself.  For example, suspend/resume action is cascaded to yet
another ops.

I would understand if this "shell" provides a few thin accessors to
the raw i915 registers.  But another layering over a single driver
implementation makes little sense in regard of abstraction.  (If there
were multiple class inherits, it's a different story, of course.)


No disagreement here Takashi.
I was planning to remove this abstraction in a second incremental pass 
that would only be on the audio side, for now keeping this layer would 
allow me to add the DisplayPort changes faster. If we simplify this now 
then I will have so many differences with the legacy code it'll be a 
nightmare. I have no emotional attachment to the legacy but it's just 
pragmatic to avoid changing everything at once.


As you also mentioned it, this second pass could also reuse all the ELD 
parsing that is still duplicated. These HDMI patches are not a 
single-shot contribution, you'll have updates coming your way.



___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915: Fix inconsistent naming of i915_guc_client parameter

2016-12-15 Thread Patchwork
== Series Details ==

Series: drm/i915: Fix inconsistent naming of i915_guc_client parameter
URL   : https://patchwork.freedesktop.org/series/16869/
State : success

== Summary ==

Series 16869v1 drm/i915: Fix inconsistent naming of i915_guc_client parameter
https://patchwork.freedesktop.org/api/1.0/series/16869/revisions/1/mbox/


fi-bdw-5557u total:247  pass:233  dwarn:0   dfail:0   fail:0   skip:14 
fi-bsw-n3050 total:247  pass:208  dwarn:0   dfail:0   fail:0   skip:39 
fi-bxt-j4205 total:247  pass:222  dwarn:0   dfail:0   fail:0   skip:25 
fi-byt-j1900 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
fi-byt-n2820 total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31 
fi-hsw-4770  total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19 
fi-hsw-4770r total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19 
fi-ilk-650   total:247  pass:195  dwarn:0   dfail:0   fail:0   skip:52 
fi-ivb-3520m total:247  pass:226  dwarn:0   dfail:0   fail:0   skip:21 
fi-kbl-7500u total:247  pass:226  dwarn:0   dfail:0   fail:0   skip:21 
fi-skl-6260u total:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13 
fi-skl-6700hqtotal:247  pass:227  dwarn:0   dfail:0   fail:0   skip:20 
fi-skl-6700k total:247  pass:224  dwarn:3   dfail:0   fail:0   skip:20 
fi-skl-6770hqtotal:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13 
fi-snb-2520m total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31 
fi-snb-2600  total:247  pass:215  dwarn:0   dfail:0   fail:0   skip:32 

639f10d1159e87cac2f85769dcd081520b904f56 drm-tip: 2016y-12m-15d-17h-57m-41s UTC 
integration manifest
e9418f8 drm/i915: Fix inconsistent naming of i915_guc_client parameter

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_3301/
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 8/9] drm/i915: Don't populate plane->plane for cursors and sprites

2016-12-15 Thread Ville Syrjälä
On Thu, Dec 15, 2016 at 05:50:02PM -0200, Paulo Zanoni wrote:
> Em Qui, 2016-12-15 às 21:11 +0200, Ville Syrjälä escreveu:
> > On Thu, Dec 15, 2016 at 05:05:05PM -0200, Paulo Zanoni wrote:
> > > 
> > > Em Ter, 2016-11-22 às 18:02 +0200, ville.syrj...@linux.intel.com
> > > escreveu:
> > > > 
> > > > From: Ville Syrjälä 
> > > > 
> > > > With plane->plane now purely reserved for the primary planes,
> > > > let's
> > > > not even populate it for cursors and sprites. Let's switch the
> > > > type
> > > > to enum plane as well since it's no longer being abused for
> > > > anything
> > > > else.
> > > 
> > > Since it's a primary plane thing, I think it makes more sense to
> > > just
> > > leave it at struct intel_crtc instead of having a field that's
> > > unused
> > > and doesn't make sense in some cases.
> > 
> > Primary plane aren't really primary planes on old platforms though.
> > That's just a software concept that has no bearing on the hardware.
> 
> Please explain more since that's not my understanding. I just opened
> the gen 2 and 3 spec docs and they do contain tons of "primary plane"
> references. I know that the hardware is a little more flexible there,

Yep. Planes can be moved to any pipe in general.

> but as far as I understand we don't even implement that. 

Not at the moment. But I have plans...

> Besides, both
> our driver and our API do have the concept of a primary plane, so it
> makes sense for the code to be organized that way, IMHO.

A plane is a plane, a pipe is a pipe. IMO you're trying to make it
more confusing by mixing up the two.

> Besides, I
> think our code organizations should always better fit the new hardware,
> since otherwise we'll make i915.ko development even harder than it is
> for new contributors/employees.

If you don't mix planes and pipes there can't be any confusion.

> 
> (And when I see those specs and realize how different the HW was, then
> I remember that in order to explain to the new people why some things
> are the way they are in our code I have to explain how the HW was 10
> years ago, I start thinking again that maybe we should just have i915-
> old.ko and i915-new.ko, since either we make our abstractions/design
> fit one thing or we make it fit another...)

From the register POV hw was almost identical up to BDW at least. It's
just a few bits (the pipe selector) that vanished from the registers.
SKL+ is a little more different but still the registers even live in the
same address.

Also given what recent history has shown us, I wouldn't be at all
surprised if we would go back to a flexible plane<->pipe assignment
in the hardware at some point in the future. A lot of the other
features that were present in old hardware has been making a comeback
in recent years.

> 
> > 
> > > 
> > > The crtc struct already includes
> > > some fields that are specific to primary planes, so I think it's a
> > > good
> > > place. Or we could create a new class: struct intel_primary_plane {
> > > struct intel_plane base; enum plane legacy_plane };
> > > 
> > > Following is a patch suggestion (probably impossible to apply due
> > > to my
> > > editor breaking long lines). Any arguments against it?
> > > 
> > > --8<--
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > > b/drivers/gpu/drm/i915/intel_display.c
> > > index bc1af87..c54b1a7 100644
> > > --- a/drivers/gpu/drm/i915/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/intel_display.c
> > > @@ -15065,14 +15065,6 @@ intel_primary_plane_create(struct
> > > drm_i915_private *dev_priv, enum pipe pipe)
> > >   state->scaler_id = -1;
> > >   }
> > >   primary->pipe = pipe;
> > > - /*
> > > -  * On gen2/3 only plane A can do FBC, but the panel fitter
> > > and
> > > LVDS
> > > -  * port is hooked to pipe B. Hence we want plane A feeding
> > > pipe B.
> > > -  */
> > > - if (HAS_FBC(dev_priv) && INTEL_GEN(dev_priv) < 4)
> > > - primary->plane = (enum plane) !pipe;
> > > - else
> > > - primary->plane = (enum plane) pipe;
> > >   primary->id = PLANE_PRIMARY;
> > >   primary->frontbuffer_bit =
> > > INTEL_FRONTBUFFER_PRIMARY(pipe);
> > >   primary->check_plane = intel_check_primary_plane;
> > > @@ -15120,7 +15112,7 @@ intel_primary_plane_create(struct
> > > drm_i915_private *dev_priv, enum pipe pipe)
> > >      0,
> > > _plane_funcs,
> > >      intel_primary_forma
> > > ts,
> > > num_formats,
> > >      DRM_PLANE_TYPE_PRIM
> > > ARY,
> > > -    "plane %c",
> > > plane_name(primary->plane));
> > > +    "plane %c",
> > > pipe_name(pipe)); /* FIXME */
> > >   if (ret)
> > >   goto fail;
> > >  
> > > @@ -15272,7 +15264,6 @@ intel_cursor_plane_create(struct
> > > drm_i915_private *dev_priv, enum pipe pipe)
> > >   

[Intel-gfx] [PATCH] drm/i915: Fix inconsistent naming of i915_guc_client parameter

2016-12-15 Thread Michal Wajdeczko
We usually use 'client' as identifier for the i915_guc_client.
For unknown reason, few functions were using 'gc' name.

Signed-off-by: Michal Wajdeczko 
---
 drivers/gpu/drm/i915/i915_guc_submission.c | 64 +++---
 1 file changed, 32 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c 
b/drivers/gpu/drm/i915/i915_guc_submission.c
index 7fa4e74..95248c9 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -344,22 +344,22 @@ static void guc_ctx_desc_fini(struct intel_guc *guc,
 int i915_guc_wq_reserve(struct drm_i915_gem_request *request)
 {
const size_t wqi_size = sizeof(struct guc_wq_item);
-   struct i915_guc_client *gc = request->i915->guc.execbuf_client;
-   struct guc_process_desc *desc = gc->vaddr + gc->proc_desc_offset;
+   struct i915_guc_client *client = request->i915->guc.execbuf_client;
+   struct guc_process_desc *desc = client->vaddr + 
client->proc_desc_offset;
u32 freespace;
int ret;
 
-   spin_lock(>wq_lock);
-   freespace = CIRC_SPACE(gc->wq_tail, desc->head, gc->wq_size);
-   freespace -= gc->wq_rsvd;
+   spin_lock(>wq_lock);
+   freespace = CIRC_SPACE(client->wq_tail, desc->head, client->wq_size);
+   freespace -= client->wq_rsvd;
if (likely(freespace >= wqi_size)) {
-   gc->wq_rsvd += wqi_size;
+   client->wq_rsvd += wqi_size;
ret = 0;
} else {
-   gc->no_wq_space++;
+   client->no_wq_space++;
ret = -EAGAIN;
}
-   spin_unlock(>wq_lock);
+   spin_unlock(>wq_lock);
 
return ret;
 }
@@ -367,17 +367,17 @@ int i915_guc_wq_reserve(struct drm_i915_gem_request 
*request)
 void i915_guc_wq_unreserve(struct drm_i915_gem_request *request)
 {
const size_t wqi_size = sizeof(struct guc_wq_item);
-   struct i915_guc_client *gc = request->i915->guc.execbuf_client;
+   struct i915_guc_client *client = request->i915->guc.execbuf_client;
 
-   GEM_BUG_ON(READ_ONCE(gc->wq_rsvd) < wqi_size);
+   GEM_BUG_ON(READ_ONCE(client->wq_rsvd) < wqi_size);
 
-   spin_lock(>wq_lock);
-   gc->wq_rsvd -= wqi_size;
-   spin_unlock(>wq_lock);
+   spin_lock(>wq_lock);
+   client->wq_rsvd -= wqi_size;
+   spin_unlock(>wq_lock);
 }
 
 /* Construct a Work Item and append it to the GuC's Work Queue */
-static void guc_wq_item_append(struct i915_guc_client *gc,
+static void guc_wq_item_append(struct i915_guc_client *client,
   struct drm_i915_gem_request *rq)
 {
/* wqi_len is in DWords, and does not include the one-word header */
@@ -388,10 +388,10 @@ static void guc_wq_item_append(struct i915_guc_client *gc,
struct guc_wq_item *wqi;
u32 freespace, tail, wq_off;
 
-   desc = gc->vaddr + gc->proc_desc_offset;
+   desc = client->vaddr + client->proc_desc_offset;
 
/* Free space is guaranteed, see i915_guc_wq_reserve() above */
-   freespace = CIRC_SPACE(gc->wq_tail, desc->head, gc->wq_size);
+   freespace = CIRC_SPACE(client->wq_tail, desc->head, client->wq_size);
GEM_BUG_ON(freespace < wqi_size);
 
/* The GuC firmware wants the tail index in QWords, not bytes */
@@ -408,17 +408,17 @@ static void guc_wq_item_append(struct i915_guc_client *gc,
 * workqueue buffer dw by dw.
 */
BUILD_BUG_ON(wqi_size != 16);
-   GEM_BUG_ON(gc->wq_rsvd < wqi_size);
+   GEM_BUG_ON(client->wq_rsvd < wqi_size);
 
/* postincrement WQ tail for next time */
-   wq_off = gc->wq_tail;
+   wq_off = client->wq_tail;
GEM_BUG_ON(wq_off & (wqi_size - 1));
-   gc->wq_tail += wqi_size;
-   gc->wq_tail &= gc->wq_size - 1;
-   gc->wq_rsvd -= wqi_size;
+   client->wq_tail += wqi_size;
+   client->wq_tail &= client->wq_size - 1;
+   client->wq_rsvd -= wqi_size;
 
/* WQ starts from the page after doorbell / process_desc */
-   wqi = gc->vaddr + wq_off + GUC_DB_SIZE;
+   wqi = client->vaddr + wq_off + GUC_DB_SIZE;
 
/* Now fill in the 4-word work queue item */
wqi->header = WQ_TYPE_INORDER |
@@ -433,30 +433,30 @@ static void guc_wq_item_append(struct i915_guc_client *gc,
wqi->fence_id = rq->global_seqno;
 }
 
-static int guc_ring_doorbell(struct i915_guc_client *gc)
+static int guc_ring_doorbell(struct i915_guc_client *client)
 {
struct guc_process_desc *desc;
union guc_doorbell_qw db_cmp, db_exc, db_ret;
union guc_doorbell_qw *db;
int attempt = 2, ret = -EAGAIN;
 
-   desc = gc->vaddr + gc->proc_desc_offset;
+   desc = client->vaddr + client->proc_desc_offset;
 
/* Update the tail so it is visible to GuC */
-   desc->tail = gc->wq_tail;
+   desc->tail = client->wq_tail;
 
/* current cookie */
db_cmp.db_status = 

Re: [Intel-gfx] [PATCH 8/9] drm/i915: Don't populate plane->plane for cursors and sprites

2016-12-15 Thread Paulo Zanoni
Em Qui, 2016-12-15 às 21:11 +0200, Ville Syrjälä escreveu:
> On Thu, Dec 15, 2016 at 05:05:05PM -0200, Paulo Zanoni wrote:
> > 
> > Em Ter, 2016-11-22 às 18:02 +0200, ville.syrj...@linux.intel.com
> > escreveu:
> > > 
> > > From: Ville Syrjälä 
> > > 
> > > With plane->plane now purely reserved for the primary planes,
> > > let's
> > > not even populate it for cursors and sprites. Let's switch the
> > > type
> > > to enum plane as well since it's no longer being abused for
> > > anything
> > > else.
> > 
> > Since it's a primary plane thing, I think it makes more sense to
> > just
> > leave it at struct intel_crtc instead of having a field that's
> > unused
> > and doesn't make sense in some cases.
> 
> Primary plane aren't really primary planes on old platforms though.
> That's just a software concept that has no bearing on the hardware.

Please explain more since that's not my understanding. I just opened
the gen 2 and 3 spec docs and they do contain tons of "primary plane"
references. I know that the hardware is a little more flexible there,
but as far as I understand we don't even implement that. Besides, both
our driver and our API do have the concept of a primary plane, so it
makes sense for the code to be organized that way, IMHO. Besides, I
think our code organizations should always better fit the new hardware,
since otherwise we'll make i915.ko development even harder than it is
for new contributors/employees.

(And when I see those specs and realize how different the HW was, then
I remember that in order to explain to the new people why some things
are the way they are in our code I have to explain how the HW was 10
years ago, I start thinking again that maybe we should just have i915-
old.ko and i915-new.ko, since either we make our abstractions/design
fit one thing or we make it fit another...)

> 
> > 
> > The crtc struct already includes
> > some fields that are specific to primary planes, so I think it's a
> > good
> > place. Or we could create a new class: struct intel_primary_plane {
> > struct intel_plane base; enum plane legacy_plane };
> > 
> > Following is a patch suggestion (probably impossible to apply due
> > to my
> > editor breaking long lines). Any arguments against it?
> > 
> > --8<--
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index bc1af87..c54b1a7 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -15065,14 +15065,6 @@ intel_primary_plane_create(struct
> > drm_i915_private *dev_priv, enum pipe pipe)
> >     state->scaler_id = -1;
> >     }
> >     primary->pipe = pipe;
> > -   /*
> > -    * On gen2/3 only plane A can do FBC, but the panel fitter
> > and
> > LVDS
> > -    * port is hooked to pipe B. Hence we want plane A feeding
> > pipe B.
> > -    */
> > -   if (HAS_FBC(dev_priv) && INTEL_GEN(dev_priv) < 4)
> > -   primary->plane = (enum plane) !pipe;
> > -   else
> > -   primary->plane = (enum plane) pipe;
> >     primary->id = PLANE_PRIMARY;
> >     primary->frontbuffer_bit =
> > INTEL_FRONTBUFFER_PRIMARY(pipe);
> >     primary->check_plane = intel_check_primary_plane;
> > @@ -15120,7 +15112,7 @@ intel_primary_plane_create(struct
> > drm_i915_private *dev_priv, enum pipe pipe)
> >        0,
> > _plane_funcs,
> >        intel_primary_forma
> > ts,
> > num_formats,
> >        DRM_PLANE_TYPE_PRIM
> > ARY,
> > -      "plane %c",
> > plane_name(primary->plane));
> > +      "plane %c",
> > pipe_name(pipe)); /* FIXME */
> >     if (ret)
> >     goto fail;
> >  
> > @@ -15272,7 +15264,6 @@ intel_cursor_plane_create(struct
> > drm_i915_private *dev_priv, enum pipe pipe)
> >     cursor->can_scale = false;
> >     cursor->max_downscale = 1;
> >     cursor->pipe = pipe;
> > -   cursor->plane = pipe;
> >     cursor->id = PLANE_CURSOR;
> >     cursor->frontbuffer_bit = INTEL_FRONTBUFFER_CURSOR(pipe);
> >     cursor->check_plane = intel_check_cursor_plane;
> > @@ -15390,7 +15381,14 @@ static int intel_crtc_init(struct
> > drm_i915_private *dev_priv, enum pipe pipe)
> >     goto fail;
> >  
> >     intel_crtc->pipe = pipe;
> > -   intel_crtc->plane = primary->plane;
> > +   /*
> > +    * On gen2/3 only plane A can do FBC, but the panel fitter
> > and
> > LVDS
> > +    * port is hooked to pipe B. Hence we want plane A feeding
> > pipe B.
> > +    */
> > +   if (HAS_FBC(dev_priv) && INTEL_GEN(dev_priv) < 4)
> > +   intel_crtc->plane = (enum plane) !pipe;
> > +   else
> > +   intel_crtc->plane = (enum plane) pipe;
> >  
> >     intel_crtc->cursor_base = ~0;
> >     intel_crtc->cursor_cntl = ~0;
> > @@ -16866,11 +16864,11 @@ void i915_redisable_vga(struct
> 

Re: [Intel-gfx] [PATCH 2/7] drm/i915: Add support for audio driver notifications

2016-12-15 Thread Pierre-Louis Bossart

On 12/14/16 7:13 AM, Takashi Iwai wrote:

On Wed, 14 Dec 2016 13:55:52 +0100,
Daniel Vetter wrote:


Only noticed it here, but why again do we need to re-roll our intel-only
hdmi/eld notification? The one we have for hda is somewhat justified since
it went in at roughly the same time as the new shared one across a bunch
of soc. But this one here is just a reinvented wheel.

And yes this code has been hanging around internally for years, but that's
kinda not a good excuse.

Obviously this comment applies to patch 1 too.


Yeah, a unified common interface would be better, really.  I'm
basically OK with the current implementation, though, as long as it
works.  But if we can sort it out quickly, it's better.

That said, we may reuse i915_audio_component stuff -- or at least,
reuse the object used there without actual component binding (the lpe
driver doesn't need the component because it's a strong dependency
unlike HD-audio case), and just add a few more fields there.
Instead of exposing the resource, we can provide the register accessor
there, too.

It's just an idea, so not necessarily serious taken.  But we can think
of unification more easily now than later.


BTW, now one thing came to my mind: don't we need the power control
(pm and power well domain) when accessing from the sound driver side?
The HD-audio component object has the gfx side callback points for
such.


The code hasn't actually been around for years. We threw away the legacy 
driver and restarted the i915 integration pretty much from scratch using 
the feedback on the intel-gfx mailing list, specifically Jesse Barnes 
and Ville Syrjala, with only basic programming sequences and register 
definitions kept on the audio side. The volume of code required on the 
i915 side was reduced by probably 50%, with useless stuff taken out left 
and right. We're down to ~500 lines changed on the i915 side with about 
400 just for the interface in the new intel_lpe_audio.c file.


The initial idea for the rework was to use the component framework. Then 
during the initial review it was suggested that component framework 
wasn't that great and that the design should follow the example of the 
VED integration with a subdevice created and pdata used to communicate 
between the i915 and audio sides. I threw the initial component 
framework patches away and we started in this direction.


There is no power domain here and in general no issue with probe 
happening independently at different times, the subdevice/pdata is 
simple enough to model the hardware. If there is an agreement to push 
for a unified interface, that's fine and I will commit to port the code 
as needed. We can modify the interface, all that's needed is to provide 
the ELD and let the audio side program a window of register space on the 
i915 side. But quite frankly I'd rather see the code being merged first 
to expand the userbase, today HDMI can only be enabled with out-of-tree 
patches pulled from my github ported on the last 6 kernel versions. I 
also plan to work an update on DisplayPort support since there are CHT 
devices on the market now.

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915: Workaround VLV/CHV DSI scanline counter hardware fail

2016-12-15 Thread Patchwork
== Series Details ==

Series: drm/i915: Workaround VLV/CHV DSI scanline counter hardware fail
URL   : https://patchwork.freedesktop.org/series/16863/
State : success

== Summary ==

Series 16863v1 drm/i915: Workaround VLV/CHV DSI scanline counter hardware fail
https://patchwork.freedesktop.org/api/1.0/series/16863/revisions/1/mbox/


fi-bdw-5557u total:247  pass:233  dwarn:0   dfail:0   fail:0   skip:14 
fi-bsw-n3050 total:247  pass:208  dwarn:0   dfail:0   fail:0   skip:39 
fi-bxt-j4205 total:247  pass:222  dwarn:0   dfail:0   fail:0   skip:25 
fi-bxt-t5700 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
fi-byt-j1900 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
fi-byt-n2820 total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31 
fi-hsw-4770  total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19 
fi-hsw-4770r total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19 
fi-ilk-650   total:247  pass:195  dwarn:0   dfail:0   fail:0   skip:52 
fi-ivb-3520m total:247  pass:226  dwarn:0   dfail:0   fail:0   skip:21 
fi-kbl-7500u total:247  pass:226  dwarn:0   dfail:0   fail:0   skip:21 
fi-skl-6260u total:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13 
fi-skl-6700hqtotal:247  pass:227  dwarn:0   dfail:0   fail:0   skip:20 
fi-skl-6700k total:247  pass:224  dwarn:3   dfail:0   fail:0   skip:20 
fi-skl-6770hqtotal:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13 
fi-snb-2520m total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31 
fi-snb-2600  total:247  pass:215  dwarn:0   dfail:0   fail:0   skip:32 

639f10d1159e87cac2f85769dcd081520b904f56 drm-tip: 2016y-12m-15d-17h-57m-41s UTC 
integration manifest
489007b drm/i915: Workaround VLV/CHV DSI scanline counter hardware fail

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_3300/
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 8/9] drm/i915: Don't populate plane->plane for cursors and sprites

2016-12-15 Thread Ville Syrjälä
On Thu, Dec 15, 2016 at 05:05:05PM -0200, Paulo Zanoni wrote:
> Em Ter, 2016-11-22 às 18:02 +0200, ville.syrj...@linux.intel.com
> escreveu:
> > From: Ville Syrjälä 
> > 
> > With plane->plane now purely reserved for the primary planes, let's
> > not even populate it for cursors and sprites. Let's switch the type
> > to enum plane as well since it's no longer being abused for anything
> > else.
> 
> Since it's a primary plane thing, I think it makes more sense to just
> leave it at struct intel_crtc instead of having a field that's unused
> and doesn't make sense in some cases.

Primary plane aren't really primary planes on old platforms though.
That's just a software concept that has no bearing on the hardware.

> The crtc struct already includes
> some fields that are specific to primary planes, so I think it's a good
> place. Or we could create a new class: struct intel_primary_plane {
> struct intel_plane base; enum plane legacy_plane };
> 
> Following is a patch suggestion (probably impossible to apply due to my
> editor breaking long lines). Any arguments against it?
> 
> --8<--
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index bc1af87..c54b1a7 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -15065,14 +15065,6 @@ intel_primary_plane_create(struct
> drm_i915_private *dev_priv, enum pipe pipe)
>   state->scaler_id = -1;
>   }
>   primary->pipe = pipe;
> - /*
> -  * On gen2/3 only plane A can do FBC, but the panel fitter and
> LVDS
> -  * port is hooked to pipe B. Hence we want plane A feeding
> pipe B.
> -  */
> - if (HAS_FBC(dev_priv) && INTEL_GEN(dev_priv) < 4)
> - primary->plane = (enum plane) !pipe;
> - else
> - primary->plane = (enum plane) pipe;
>   primary->id = PLANE_PRIMARY;
>   primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe);
>   primary->check_plane = intel_check_primary_plane;
> @@ -15120,7 +15112,7 @@ intel_primary_plane_create(struct
> drm_i915_private *dev_priv, enum pipe pipe)
>      0, _plane_funcs,
>      intel_primary_formats,
> num_formats,
>      DRM_PLANE_TYPE_PRIMARY,
> -    "plane %c",
> plane_name(primary->plane));
> +    "plane %c",
> pipe_name(pipe)); /* FIXME */
>   if (ret)
>   goto fail;
>  
> @@ -15272,7 +15264,6 @@ intel_cursor_plane_create(struct
> drm_i915_private *dev_priv, enum pipe pipe)
>   cursor->can_scale = false;
>   cursor->max_downscale = 1;
>   cursor->pipe = pipe;
> - cursor->plane = pipe;
>   cursor->id = PLANE_CURSOR;
>   cursor->frontbuffer_bit = INTEL_FRONTBUFFER_CURSOR(pipe);
>   cursor->check_plane = intel_check_cursor_plane;
> @@ -15390,7 +15381,14 @@ static int intel_crtc_init(struct
> drm_i915_private *dev_priv, enum pipe pipe)
>   goto fail;
>  
>   intel_crtc->pipe = pipe;
> - intel_crtc->plane = primary->plane;
> + /*
> +  * On gen2/3 only plane A can do FBC, but the panel fitter and
> LVDS
> +  * port is hooked to pipe B. Hence we want plane A feeding
> pipe B.
> +  */
> + if (HAS_FBC(dev_priv) && INTEL_GEN(dev_priv) < 4)
> + intel_crtc->plane = (enum plane) !pipe;
> + else
> + intel_crtc->plane = (enum plane) pipe;
>  
>   intel_crtc->cursor_base = ~0;
>   intel_crtc->cursor_cntl = ~0;
> @@ -16866,11 +16864,11 @@ void i915_redisable_vga(struct
> drm_i915_private *dev_priv)
>   intel_display_power_put(dev_priv, POWER_DOMAIN_VGA);
>  }
>  
> -static bool primary_get_hw_state(struct intel_plane *plane)
> +static bool primary_get_hw_state(struct intel_crtc *crtc)
>  {
> - struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  
> - return I915_READ(DSPCNTR(plane->plane)) &
> DISPLAY_PLANE_ENABLE;
> + return I915_READ(DSPCNTR(crtc->plane)) & DISPLAY_PLANE_ENABLE;
>  }
>  
>  /* FIXME read out full plane state for all planes */
> @@ -16880,8 +16878,7 @@ static void readout_plane_state(struct
> intel_crtc *crtc)
>   struct intel_plane_state *plane_state =
>   to_intel_plane_state(primary->state);
>  
> - plane_state->base.visible = crtc->active &&
> - primary_get_hw_state(to_intel_plane(primary));
> + plane_state->base.visible = crtc->active &&
> primary_get_hw_state(crtc);
>  
>   if (plane_state->base.visible)
>   crtc->base.state->plane_mask |= 1 <<
> drm_plane_index(primary);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index 362f698..b2bdd49 100644
> --- 

Re: [Intel-gfx] [PATCH 8/9] drm/i915: Don't populate plane->plane for cursors and sprites

2016-12-15 Thread Paulo Zanoni
Em Ter, 2016-11-22 às 18:02 +0200, ville.syrj...@linux.intel.com
escreveu:
> From: Ville Syrjälä 
> 
> With plane->plane now purely reserved for the primary planes, let's
> not even populate it for cursors and sprites. Let's switch the type
> to enum plane as well since it's no longer being abused for anything
> else.

Since it's a primary plane thing, I think it makes more sense to just
leave it at struct intel_crtc instead of having a field that's unused
and doesn't make sense in some cases. The crtc struct already includes
some fields that are specific to primary planes, so I think it's a good
place. Or we could create a new class: struct intel_primary_plane {
struct intel_plane base; enum plane legacy_plane };

Following is a patch suggestion (probably impossible to apply due to my
editor breaking long lines). Any arguments against it?

--8<--

diff --git a/drivers/gpu/drm/i915/intel_display.c
b/drivers/gpu/drm/i915/intel_display.c
index bc1af87..c54b1a7 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -15065,14 +15065,6 @@ intel_primary_plane_create(struct
drm_i915_private *dev_priv, enum pipe pipe)
    state->scaler_id = -1;
    }
    primary->pipe = pipe;
-   /*
-    * On gen2/3 only plane A can do FBC, but the panel fitter and
LVDS
-    * port is hooked to pipe B. Hence we want plane A feeding
pipe B.
-    */
-   if (HAS_FBC(dev_priv) && INTEL_GEN(dev_priv) < 4)
-   primary->plane = (enum plane) !pipe;
-   else
-   primary->plane = (enum plane) pipe;
    primary->id = PLANE_PRIMARY;
    primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe);
    primary->check_plane = intel_check_primary_plane;
@@ -15120,7 +15112,7 @@ intel_primary_plane_create(struct
drm_i915_private *dev_priv, enum pipe pipe)
       0, _plane_funcs,
       intel_primary_formats,
num_formats,
       DRM_PLANE_TYPE_PRIMARY,
-      "plane %c",
plane_name(primary->plane));
+      "plane %c",
pipe_name(pipe)); /* FIXME */
    if (ret)
    goto fail;
 
@@ -15272,7 +15264,6 @@ intel_cursor_plane_create(struct
drm_i915_private *dev_priv, enum pipe pipe)
    cursor->can_scale = false;
    cursor->max_downscale = 1;
    cursor->pipe = pipe;
-   cursor->plane = pipe;
    cursor->id = PLANE_CURSOR;
    cursor->frontbuffer_bit = INTEL_FRONTBUFFER_CURSOR(pipe);
    cursor->check_plane = intel_check_cursor_plane;
@@ -15390,7 +15381,14 @@ static int intel_crtc_init(struct
drm_i915_private *dev_priv, enum pipe pipe)
    goto fail;
 
    intel_crtc->pipe = pipe;
-   intel_crtc->plane = primary->plane;
+   /*
+    * On gen2/3 only plane A can do FBC, but the panel fitter and
LVDS
+    * port is hooked to pipe B. Hence we want plane A feeding
pipe B.
+    */
+   if (HAS_FBC(dev_priv) && INTEL_GEN(dev_priv) < 4)
+   intel_crtc->plane = (enum plane) !pipe;
+   else
+   intel_crtc->plane = (enum plane) pipe;
 
    intel_crtc->cursor_base = ~0;
    intel_crtc->cursor_cntl = ~0;
@@ -16866,11 +16864,11 @@ void i915_redisable_vga(struct
drm_i915_private *dev_priv)
    intel_display_power_put(dev_priv, POWER_DOMAIN_VGA);
 }
 
-static bool primary_get_hw_state(struct intel_plane *plane)
+static bool primary_get_hw_state(struct intel_crtc *crtc)
 {
-   struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+   struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
-   return I915_READ(DSPCNTR(plane->plane)) &
DISPLAY_PLANE_ENABLE;
+   return I915_READ(DSPCNTR(crtc->plane)) & DISPLAY_PLANE_ENABLE;
 }
 
 /* FIXME read out full plane state for all planes */
@@ -16880,8 +16878,7 @@ static void readout_plane_state(struct
intel_crtc *crtc)
    struct intel_plane_state *plane_state =
    to_intel_plane_state(primary->state);
 
-   plane_state->base.visible = crtc->active &&
-   primary_get_hw_state(to_intel_plane(primary));
+   plane_state->base.visible = crtc->active &&
primary_get_hw_state(crtc);
 
    if (plane_state->base.visible)
    crtc->base.state->plane_mask |= 1 <<
drm_plane_index(primary);
diff --git a/drivers/gpu/drm/i915/intel_drv.h
b/drivers/gpu/drm/i915/intel_drv.h
index 362f698..b2bdd49 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -767,7 +767,6 @@ struct intel_plane_wm_parameters {
 
 struct intel_plane {
    struct drm_plane base;
-   u8 plane;
    enum plane_id id;
    enum pipe pipe;
    bool can_scale;
diff --git a/drivers/gpu/drm/i915/intel_sprite.c

Re: [Intel-gfx] [alsa-devel] [PATCH 1/7] drm/i915: setup bridge for HDMI LPE audio driver

2016-12-15 Thread Pierre-Louis Bossart


>>> +static void lpe_audio_irq_unmask(struct irq_data *d) {
>>> +  struct drm_i915_private *dev_priv = d->chip_data;
>>> +  unsigned long irqflags;
>>> +  u32 val = (I915_LPE_PIPE_A_INTERRUPT |
>>> +  I915_LPE_PIPE_B_INTERRUPT);
>>
>> PIPE_C missing?
>>
>
> No PIPE_C on vlv

Good catch Daniel.
We initially had PIPE_C everyhwere, thinking that it's harmless on 
Baytrail. Ville had a comment that there was no PIPE_C on BYT so we 
removed it for Baytrail-only code, here it makes no sense to me. we have 
the same problem in lpe_audio_irq_mask


>> Besides the few bikesheds seems all reasonable, with those addressed
>>
>> Acked-by: Daniel Vetter 
>>
>
> Thanks
>
>> ... for merging through sound tree. Since we're super early in 4.11 
a topic

>> branch for me to pull in to avoid sync headaches would be good.

Thanks for the reviews and ack, we'll fix the comments shortly.
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 1/2] drm/i915/huc: Introduce enable_huc parameter

2016-12-15 Thread Srivatsa, Anusha


>-Original Message-
>From: Wajdeczko, Michal
>Sent: Thursday, December 15, 2016 10:32 AM
>To: Srivatsa, Anusha 
>Cc: intel-gfx@lists.freedesktop.org; Nikula, Jani 
>Subject: Re: [Intel-gfx] [PATCH 1/2] drm/i915/huc: Introduce enable_huc
>parameter
>
>On Thu, Dec 15, 2016 at 10:24:56AM -0800, anushasr wrote:
>> From: Anusha Srivatsa 
>>
>> Add a new kernel parameter: enable_huc. This parameter controls HuC
>> functionality. If this parameter is set to 1, it suggests that HuC
>> functionality is being used and also that the GuC has to be loaded.
>> GuC has to be loaded in order to authenticate the HuC.
>>
>> Cc: Jani Nikula 
>> Cc: Chris Wilson 
>> Cc: Tvrtko Ursulin 
>> Cc: Arek 
>> Signed-off-by: Anusha Srivatsa 
>> ---
>>  drivers/gpu/drm/i915/i915_params.c  | 5 +
>>  drivers/gpu/drm/i915/i915_params.h  | 1 +
>>  drivers/gpu/drm/i915/intel_huc_loader.c | 4 
>>  3 files changed, 10 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_params.c
>> b/drivers/gpu/drm/i915/i915_params.c
>> index 0e280fb..1d9c306 100644
>> --- a/drivers/gpu/drm/i915/i915_params.c
>> +++ b/drivers/gpu/drm/i915/i915_params.c
>> @@ -56,6 +56,7 @@ struct i915_params i915 __read_mostly = {
>>  .verbose_state_checks = 1,
>>  .nuclear_pageflip = 0,
>>  .edp_vswing = 0,
>> +.enable_huc = 1,
>>  .enable_guc_loading = 0,
>>  .enable_guc_submission = 0,
>>  .guc_log_level = -1,
>> @@ -216,6 +217,10 @@ MODULE_PARM_DESC(edp_vswing,
>>   "(0=use value from vbt [default], 1=low power swing(200mV),"
>>   "2=default swing(400mV))");
>>
>> +module_param_named(enable_huc, i915.enable_huc, int, 0400);
>> +MODULE_PARM_DESC(enable_huc,
>> +"Enable HuC usage. If enabled,load GuC (1:enabled (default),
>> +0:disabled)");
>> +
>>  module_param_named_unsafe(enable_guc_loading,
>> i915.enable_guc_loading, int, 0400);
>MODULE_PARM_DESC(enable_guc_loading,
>>  "Enable GuC firmware loading "
>> diff --git a/drivers/gpu/drm/i915/i915_params.h
>> b/drivers/gpu/drm/i915/i915_params.h
>> index 8e433de..7b0523b 100644
>> --- a/drivers/gpu/drm/i915/i915_params.h
>> +++ b/drivers/gpu/drm/i915/i915_params.h
>> @@ -44,6 +44,7 @@ struct i915_params {
>>  int disable_power_well;
>>  int enable_ips;
>>  int invert_brightness;
>> +int enable_huc;
>>  int enable_guc_loading;
>>  int enable_guc_submission;
>>  int guc_log_level;
>> diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c
>> b/drivers/gpu/drm/i915/intel_huc_loader.c
>> index 8137979..a545f76 100644
>> --- a/drivers/gpu/drm/i915/intel_huc_loader.c
>> +++ b/drivers/gpu/drm/i915/intel_huc_loader.c
>> @@ -166,6 +166,10 @@ void intel_huc_init(struct drm_i915_private *dev_priv)
>>  huc_fw->load_status = INTEL_UC_FIRMWARE_NONE;
>>  huc_fw->fw_type = INTEL_UC_FW_TYPE_HUC;
>>
>> +if (!i915.enable_huc)
>> +DRM_ERROR("HuC not enabled. Will not be loaded\n");
>
>Is this really an error ? Maybe DRM_INFO ?
>What if value of this param conflicts with HAS_HUC_UCODE ?
>Shouldn't we have some 'sanitize' code for this ?
>Or maybe we should check this param after HAS_HUC check below ?
>
DRM_Info might be a good idea. But I feel this is the right place for this. 
Since we first check if HuC is there or not, if not there then return 
immediately. If present then go ahead and do the check below.

Anusha
>Michal
>
>> +return;
>> +
>>  if (!HAS_HUC_UCODE(dev_priv))
>>  return;
>>
>> --
>> 2.7.4
>>
>> ___
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 7/9] drm/i915: s/plane/plane_id/ in skl+ plane register defines

2016-12-15 Thread Paulo Zanoni
Em Ter, 2016-11-22 às 18:02 +0200, ville.syrj...@linux.intel.com
escreveu:
> From: Ville Syrjälä 
> 
> Rename the SKL plane register define 'plane' parameter to 'plane_id'
> to
> reflect the fact that you're supposed to pass in the enum plane_id
> rather than enum plane.
> 
> Do the same for the scaler plane selector bits.
> 

Reviewed-by: Paulo Zanoni 

> Cc: Paulo Zanoni 
> Suggested-by: Paulo Zanoni 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/i915_reg.h | 46 ---
> --
>  1 file changed, 23 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h
> b/drivers/gpu/drm/i915/i915_reg.h
> index d03491089f9c..8ceea23ba63b 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -5502,8 +5502,8 @@ enum {
>  #define _PLANE_CTL_1(pipe)   _PIPE(pipe, _PLANE_CTL_1_A,
> _PLANE_CTL_1_B)
>  #define _PLANE_CTL_2(pipe)   _PIPE(pipe, _PLANE_CTL_2_A,
> _PLANE_CTL_2_B)
>  #define _PLANE_CTL_3(pipe)   _PIPE(pipe, _PLANE_CTL_3_A,
> _PLANE_CTL_3_B)
> -#define PLANE_CTL(pipe, plane)   \
> - _MMIO_PLANE(plane, _PLANE_CTL_1(pipe), _PLANE_CTL_2(pipe))
> +#define PLANE_CTL(pipe, plane_id)\
> + _MMIO_PLANE(plane_id, _PLANE_CTL_1(pipe),
> _PLANE_CTL_2(pipe))
>  
>  #define _PLANE_STRIDE_1_B0x71188
>  #define _PLANE_STRIDE_2_B0x71288
> @@ -5514,8 +5514,8 @@ enum {
>   _PIPE(pipe, _PLANE_STRIDE_2_A, _PLANE_STRIDE_2_B)
>  #define _PLANE_STRIDE_3(pipe)\
>   _PIPE(pipe, _PLANE_STRIDE_3_A, _PLANE_STRIDE_3_B)
> -#define PLANE_STRIDE(pipe, plane)\
> - _MMIO_PLANE(plane, _PLANE_STRIDE_1(pipe),
> _PLANE_STRIDE_2(pipe))
> +#define PLANE_STRIDE(pipe, plane_id) \
> + _MMIO_PLANE(plane_id, _PLANE_STRIDE_1(pipe),
> _PLANE_STRIDE_2(pipe))
>  
>  #define _PLANE_POS_1_B   0x7118c
>  #define _PLANE_POS_2_B   0x7128c
> @@ -5523,8 +5523,8 @@ enum {
>  #define _PLANE_POS_1(pipe)   _PIPE(pipe, _PLANE_POS_1_A,
> _PLANE_POS_1_B)
>  #define _PLANE_POS_2(pipe)   _PIPE(pipe, _PLANE_POS_2_A,
> _PLANE_POS_2_B)
>  #define _PLANE_POS_3(pipe)   _PIPE(pipe, _PLANE_POS_3_A,
> _PLANE_POS_3_B)
> -#define PLANE_POS(pipe, plane)   \
> - _MMIO_PLANE(plane, _PLANE_POS_1(pipe), _PLANE_POS_2(pipe))
> +#define PLANE_POS(pipe, plane_id)\
> + _MMIO_PLANE(plane_id, _PLANE_POS_1(pipe),
> _PLANE_POS_2(pipe))
>  
>  #define _PLANE_SIZE_1_B  0x71190
>  #define _PLANE_SIZE_2_B  0x71290
> @@ -5532,8 +5532,8 @@ enum {
>  #define _PLANE_SIZE_1(pipe)  _PIPE(pipe, _PLANE_SIZE_1_A,
> _PLANE_SIZE_1_B)
>  #define _PLANE_SIZE_2(pipe)  _PIPE(pipe, _PLANE_SIZE_2_A,
> _PLANE_SIZE_2_B)
>  #define _PLANE_SIZE_3(pipe)  _PIPE(pipe, _PLANE_SIZE_3_A,
> _PLANE_SIZE_3_B)
> -#define PLANE_SIZE(pipe, plane)  \
> - _MMIO_PLANE(plane, _PLANE_SIZE_1(pipe), _PLANE_SIZE_2(pipe))
> +#define PLANE_SIZE(pipe, plane_id)   \
> + _MMIO_PLANE(plane_id, _PLANE_SIZE_1(pipe),
> _PLANE_SIZE_2(pipe))
>  
>  #define _PLANE_SURF_1_B  0x7119c
>  #define _PLANE_SURF_2_B  0x7129c
> @@ -5541,36 +5541,36 @@ enum {
>  #define _PLANE_SURF_1(pipe)  _PIPE(pipe, _PLANE_SURF_1_A,
> _PLANE_SURF_1_B)
>  #define _PLANE_SURF_2(pipe)  _PIPE(pipe, _PLANE_SURF_2_A,
> _PLANE_SURF_2_B)
>  #define _PLANE_SURF_3(pipe)  _PIPE(pipe, _PLANE_SURF_3_A,
> _PLANE_SURF_3_B)
> -#define PLANE_SURF(pipe, plane)  \
> - _MMIO_PLANE(plane, _PLANE_SURF_1(pipe), _PLANE_SURF_2(pipe))
> +#define PLANE_SURF(pipe, plane_id)   \
> + _MMIO_PLANE(plane_id, _PLANE_SURF_1(pipe),
> _PLANE_SURF_2(pipe))
>  
>  #define _PLANE_OFFSET_1_B0x711a4
>  #define _PLANE_OFFSET_2_B0x712a4
>  #define _PLANE_OFFSET_1(pipe) _PIPE(pipe, _PLANE_OFFSET_1_A,
> _PLANE_OFFSET_1_B)
>  #define _PLANE_OFFSET_2(pipe) _PIPE(pipe, _PLANE_OFFSET_2_A,
> _PLANE_OFFSET_2_B)
> -#define PLANE_OFFSET(pipe, plane)\
> - _MMIO_PLANE(plane, _PLANE_OFFSET_1(pipe),
> _PLANE_OFFSET_2(pipe))
> +#define PLANE_OFFSET(pipe, plane_id) \
> + _MMIO_PLANE(plane_id, _PLANE_OFFSET_1(pipe),
> _PLANE_OFFSET_2(pipe))
>  
>  #define _PLANE_KEYVAL_1_B0x71194
>  #define _PLANE_KEYVAL_2_B0x71294
>  #define _PLANE_KEYVAL_1(pipe) _PIPE(pipe, _PLANE_KEYVAL_1_A,
> _PLANE_KEYVAL_1_B)
>  #define _PLANE_KEYVAL_2(pipe) _PIPE(pipe, _PLANE_KEYVAL_2_A,
> _PLANE_KEYVAL_2_B)
> -#define PLANE_KEYVAL(pipe, plane)\
> - _MMIO_PLANE(plane, _PLANE_KEYVAL_1(pipe),
> _PLANE_KEYVAL_2(pipe))
> +#define PLANE_KEYVAL(pipe, plane_id) \
> + _MMIO_PLANE(plane_id, _PLANE_KEYVAL_1(pipe),
> _PLANE_KEYVAL_2(pipe))
>  
>  #define _PLANE_KEYMSK_1_B0x71198
>  #define _PLANE_KEYMSK_2_B

Re: [Intel-gfx] [PATCH 1/2] drm/i915/huc: Introduce enable_huc parameter

2016-12-15 Thread Michal Wajdeczko
On Thu, Dec 15, 2016 at 10:24:56AM -0800, anushasr wrote:
> From: Anusha Srivatsa 
> 
> Add a new kernel parameter: enable_huc. This parameter
> controls HuC functionality. If this parameter
> is set to 1, it suggests that HuC functionality is being
> used and also that the GuC has to be loaded. GuC has to be
> loaded in order to authenticate the HuC.
> 
> Cc: Jani Nikula 
> Cc: Chris Wilson 
> Cc: Tvrtko Ursulin 
> Cc: Arek 
> Signed-off-by: Anusha Srivatsa 
> ---
>  drivers/gpu/drm/i915/i915_params.c  | 5 +
>  drivers/gpu/drm/i915/i915_params.h  | 1 +
>  drivers/gpu/drm/i915/intel_huc_loader.c | 4 
>  3 files changed, 10 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_params.c 
> b/drivers/gpu/drm/i915/i915_params.c
> index 0e280fb..1d9c306 100644
> --- a/drivers/gpu/drm/i915/i915_params.c
> +++ b/drivers/gpu/drm/i915/i915_params.c
> @@ -56,6 +56,7 @@ struct i915_params i915 __read_mostly = {
>   .verbose_state_checks = 1,
>   .nuclear_pageflip = 0,
>   .edp_vswing = 0,
> + .enable_huc = 1,
>   .enable_guc_loading = 0,
>   .enable_guc_submission = 0,
>   .guc_log_level = -1,
> @@ -216,6 +217,10 @@ MODULE_PARM_DESC(edp_vswing,
>"(0=use value from vbt [default], 1=low power swing(200mV),"
>"2=default swing(400mV))");
>  
> +module_param_named(enable_huc, i915.enable_huc, int, 0400);
> +MODULE_PARM_DESC(enable_huc,
> + "Enable HuC usage. If enabled,load GuC (1:enabled (default), 
> 0:disabled)");
> +
>  module_param_named_unsafe(enable_guc_loading, i915.enable_guc_loading, int, 
> 0400);
>  MODULE_PARM_DESC(enable_guc_loading,
>   "Enable GuC firmware loading "
> diff --git a/drivers/gpu/drm/i915/i915_params.h 
> b/drivers/gpu/drm/i915/i915_params.h
> index 8e433de..7b0523b 100644
> --- a/drivers/gpu/drm/i915/i915_params.h
> +++ b/drivers/gpu/drm/i915/i915_params.h
> @@ -44,6 +44,7 @@ struct i915_params {
>   int disable_power_well;
>   int enable_ips;
>   int invert_brightness;
> + int enable_huc;
>   int enable_guc_loading;
>   int enable_guc_submission;
>   int guc_log_level;
> diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c 
> b/drivers/gpu/drm/i915/intel_huc_loader.c
> index 8137979..a545f76 100644
> --- a/drivers/gpu/drm/i915/intel_huc_loader.c
> +++ b/drivers/gpu/drm/i915/intel_huc_loader.c
> @@ -166,6 +166,10 @@ void intel_huc_init(struct drm_i915_private *dev_priv)
>   huc_fw->load_status = INTEL_UC_FIRMWARE_NONE;
>   huc_fw->fw_type = INTEL_UC_FW_TYPE_HUC;
>  
> + if (!i915.enable_huc)
> + DRM_ERROR("HuC not enabled. Will not be loaded\n");

Is this really an error ? Maybe DRM_INFO ?
What if value of this param conflicts with HAS_HUC_UCODE ?
Shouldn't we have some 'sanitize' code for this ?
Or maybe we should check this param after HAS_HUC check below ?

Michal

> + return;
> +
>   if (!HAS_HUC_UCODE(dev_priv))
>   return;
>  
> -- 
> 2.7.4
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 1/2] drm/i915/huc: Introduce enable_huc parameter

2016-12-15 Thread anushasr
From: Anusha Srivatsa 

Add a new kernel parameter: enable_huc. This parameter
controls HuC functionality. If this parameter
is set to 1, it suggests that HuC functionality is being
used and also that the GuC has to be loaded. GuC has to be
loaded in order to authenticate the HuC.

Cc: Jani Nikula 
Cc: Chris Wilson 
Cc: Tvrtko Ursulin 
Cc: Arek 
Signed-off-by: Anusha Srivatsa 
---
 drivers/gpu/drm/i915/i915_params.c  | 5 +
 drivers/gpu/drm/i915/i915_params.h  | 1 +
 drivers/gpu/drm/i915/intel_huc_loader.c | 4 
 3 files changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_params.c 
b/drivers/gpu/drm/i915/i915_params.c
index 0e280fb..1d9c306 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -56,6 +56,7 @@ struct i915_params i915 __read_mostly = {
.verbose_state_checks = 1,
.nuclear_pageflip = 0,
.edp_vswing = 0,
+   .enable_huc = 1,
.enable_guc_loading = 0,
.enable_guc_submission = 0,
.guc_log_level = -1,
@@ -216,6 +217,10 @@ MODULE_PARM_DESC(edp_vswing,
 "(0=use value from vbt [default], 1=low power swing(200mV),"
 "2=default swing(400mV))");
 
+module_param_named(enable_huc, i915.enable_huc, int, 0400);
+MODULE_PARM_DESC(enable_huc,
+   "Enable HuC usage. If enabled,load GuC (1:enabled (default), 
0:disabled)");
+
 module_param_named_unsafe(enable_guc_loading, i915.enable_guc_loading, int, 
0400);
 MODULE_PARM_DESC(enable_guc_loading,
"Enable GuC firmware loading "
diff --git a/drivers/gpu/drm/i915/i915_params.h 
b/drivers/gpu/drm/i915/i915_params.h
index 8e433de..7b0523b 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -44,6 +44,7 @@ struct i915_params {
int disable_power_well;
int enable_ips;
int invert_brightness;
+   int enable_huc;
int enable_guc_loading;
int enable_guc_submission;
int guc_log_level;
diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c 
b/drivers/gpu/drm/i915/intel_huc_loader.c
index 8137979..a545f76 100644
--- a/drivers/gpu/drm/i915/intel_huc_loader.c
+++ b/drivers/gpu/drm/i915/intel_huc_loader.c
@@ -166,6 +166,10 @@ void intel_huc_init(struct drm_i915_private *dev_priv)
huc_fw->load_status = INTEL_UC_FIRMWARE_NONE;
huc_fw->fw_type = INTEL_UC_FW_TYPE_HUC;
 
+   if (!i915.enable_huc)
+   DRM_ERROR("HuC not enabled. Will not be loaded\n");
+   return;
+
if (!HAS_HUC_UCODE(dev_priv))
return;
 
-- 
2.7.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 2/2] drm/i915/guc: Remove enable_guc_loading parameter.

2016-12-15 Thread anushasr
Remove the enable_guc_loading parameter. GuC loads are now
controlled through enable_huc and enable_guc_submission
parameter. If either or both of these parameters are set.
GuC is loaded.

If we need to debug GuC we can do so by removing the firmware from
the rootfs instead of disabling with a parameter. So besides enabling
guc by default this patch also kill the use of the parameter for
loading.

Cc: Jani Nikula 
Cc: Chris Wilson 
Cc: Tvrtko Ursulin 
Cc: Arek 
Signed-off-by: Anusha Srivatsa 
---
 drivers/gpu/drm/i915/i915_params.c  |  6 --
 drivers/gpu/drm/i915/i915_params.h  |  1 -
 drivers/gpu/drm/i915/intel_guc_loader.c | 27 +--
 3 files changed, 9 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_params.c 
b/drivers/gpu/drm/i915/i915_params.c
index 1d9c306..55c050f 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -57,7 +57,6 @@ struct i915_params i915 __read_mostly = {
.nuclear_pageflip = 0,
.edp_vswing = 0,
.enable_huc = 1,
-   .enable_guc_loading = 0,
.enable_guc_submission = 0,
.guc_log_level = -1,
.enable_dp_mst = true,
@@ -221,11 +220,6 @@ module_param_named(enable_huc, i915.enable_huc, int, 0400);
 MODULE_PARM_DESC(enable_huc,
"Enable HuC usage. If enabled,load GuC (1:enabled (default), 
0:disabled)");
 
-module_param_named_unsafe(enable_guc_loading, i915.enable_guc_loading, int, 
0400);
-MODULE_PARM_DESC(enable_guc_loading,
-   "Enable GuC firmware loading "
-   "(-1=auto, 0=never [default], 1=if available, 2=required)");
-
 module_param_named_unsafe(enable_guc_submission, i915.enable_guc_submission, 
int, 0400);
 MODULE_PARM_DESC(enable_guc_submission,
"Enable GuC submission "
diff --git a/drivers/gpu/drm/i915/i915_params.h 
b/drivers/gpu/drm/i915/i915_params.h
index 7b0523b..3599329 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -45,7 +45,6 @@ struct i915_params {
int enable_ips;
int invert_brightness;
int enable_huc;
-   int enable_guc_loading;
int enable_guc_submission;
int guc_log_level;
int use_mmio_flip;
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c 
b/drivers/gpu/drm/i915/intel_guc_loader.c
index 85c0a2a..c09fdc8 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -459,10 +459,9 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
intel_uc_fw_status_repr(guc_fw->fetch_status),
intel_uc_fw_status_repr(guc_fw->load_status));
 
-   /* Loading forbidden, or no firmware to load? */
-   if (!i915.enable_guc_loading) {
-   err = 0;
-   goto fail;
+   if (!HAS_GUC(dev_priv)) {
+   /* Platform does not have a GuC */
+   return 0;
} else if (fw_path == NULL) {
/* Device is known to have no uCode (e.g. no GuC) */
err = -ENXIO;
@@ -560,9 +559,7 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
 * nonfatal error (i.e. it doesn't prevent driver load, but
 * marks the GPU as wedged until reset).
 */
-   if (i915.enable_guc_loading > 1) {
-   ret = -EIO;
-   } else if (i915.enable_guc_submission > 1) {
+   if (i915.enable_guc_submission > 1) {
ret = -EIO;
} else {
ret = 0;
@@ -743,14 +740,11 @@ void intel_guc_init(struct drm_i915_private *dev_priv)
const char *fw_path;
 
if (!HAS_GUC(dev_priv)) {
-   i915.enable_guc_loading = 0;
-   i915.enable_guc_submission = 0;
-   } else {
-   /* A negative value means "use platform default" */
-   if (i915.enable_guc_loading < 0)
-   i915.enable_guc_loading = HAS_GUC_UCODE(dev_priv);
-   if (i915.enable_guc_submission < 0)
-   i915.enable_guc_submission = HAS_GUC_SCHED(dev_priv);
+   return;
+   } else if ((!i915.enable_huc) && (!i915.enable_guc_submission)) {
+   /* Both enable_huc and enable_guc_submission is disabled */
+   DRM_ERROR("GuC will not be loaded\n");
+   return;
}
 
if (!HAS_GUC_UCODE(dev_priv)) {
@@ -775,9 +769,6 @@ void intel_guc_init(struct drm_i915_private *dev_priv)
guc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
guc_fw->load_status = INTEL_UC_FIRMWARE_NONE;
 
-   /* Early (and silent) return if GuC loading is disabled */
-   if (!i915.enable_guc_loading)
-   return;
if (fw_path == NULL)
return;
if (*fw_path == '\0')
-- 
2.7.4

___

[Intel-gfx] ✗ Fi.CI.BAT: failure for GuC Scrub vol. 1

2016-12-15 Thread Patchwork
== Series Details ==

Series: GuC Scrub vol. 1
URL   : https://patchwork.freedesktop.org/series/16856/
State : failure

== Summary ==

Series 16856v1 GuC Scrub vol. 1
https://patchwork.freedesktop.org/api/1.0/series/16856/revisions/1/mbox/

Test drv_module_reload:
Subgroup basic-reload-inject:
pass   -> INCOMPLETE (fi-kbl-7500u)
Test kms_pipe_crc_basic:
Subgroup bad-nb-words-1:
dmesg-warn -> PASS   (fi-snb-2520m)
Subgroup suspend-read-crc-pipe-a:
skip   -> PASS   (fi-bxt-j4205)

fi-bdw-5557u total:247  pass:233  dwarn:0   dfail:0   fail:0   skip:14 
fi-bsw-n3050 total:247  pass:208  dwarn:0   dfail:0   fail:0   skip:39 
fi-bxt-j4205 total:247  pass:223  dwarn:0   dfail:0   fail:0   skip:24 
fi-bxt-t5700 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
fi-byt-j1900 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
fi-byt-n2820 total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31 
fi-hsw-4770  total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19 
fi-hsw-4770r total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19 
fi-ilk-650   total:247  pass:195  dwarn:0   dfail:0   fail:0   skip:52 
fi-ivb-3520m total:247  pass:226  dwarn:0   dfail:0   fail:0   skip:21 
fi-kbl-7500u total:7pass:6dwarn:0   dfail:0   fail:0   skip:0  
fi-skl-6260u total:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13 
fi-skl-6700hqtotal:247  pass:227  dwarn:0   dfail:0   fail:0   skip:20 
fi-skl-6700k total:247  pass:224  dwarn:3   dfail:0   fail:0   skip:20 
fi-skl-6770hqtotal:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13 
fi-snb-2520m total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31 
fi-snb-2600  total:247  pass:215  dwarn:0   dfail:0   fail:0   skip:32 

a16fc233af5c80d1ed23178c94b7fbb77e48ffe0 drm-tip: 2016y-12m-15d-15h-21m-31s UTC 
integration manifest
056221b drm/i915/guc: Simplify guc_fw_path
6b29b79 drm/i915/guc: Extract param logic form guc_init
16d3647 drm/i915/guc: Simplify intel_guc_load()
b4d985a drm/i915/guc: Introduce intel_uc_init()
7d2e815 drm/i915/guc: Rename _setup() to _load()

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_3298/
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915: Workaround VLV/CHV DSI scanline counter hardware fail

2016-12-15 Thread ville . syrjala
From: Ville Syrjälä 

The scanline counter is bonkers on VLV/CHV DSI. The scanline counter
increment is not lined up with the start of vblank like it is on
every other platform and output type. This causes problems for
both the vblank timestamping and atomic update vblank evasion.

On my FFRD8 machine at least, the scanline counter increment
happens about 1/3 of a scanline ahead of the start of vblank (which
is where all register latching happens still). That means we can't
trust the scanline counter to tell us whether we're in vblank or not
while we're on that particular line. In order to keep vblank
timestamping in working condition when called from the vblank irq,
we'll leave scanline_offset at one, which means that the entire
line containing the start of vblank is considered to be inside
the vblank.

For the vblank evasion we'll need to consider that entire line
to be bad, since we can't tell whether the registers already
got latched or not. And we can't actually use the start of vblank
interrupt to get us past that line as the interrupt would fire
too soon, and then we'd up waiting for the next start of vblank
instead. One way around that would using the frame start
interrupt instead since that wouldn't fire until the next
scanline, but that would require some bigger changes in the
interrupt code. So for simplicity we'll just poll until we get
past the bad line.

v2: Adjust the comments a bit

Cc: sta...@vger.kernel.org
Cc: Jonas Aaberg 
Tested-by: Jonas Aaberg 
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99086
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/intel_display.c |  9 +
 drivers/gpu/drm/i915/intel_sprite.c  | 21 +
 2 files changed, 30 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 9cc5dbfc314b..159b2eb9766b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13852,6 +13852,15 @@ static void update_scanline_offset(struct intel_crtc 
*crtc)
 * type. For DP ports it behaves like most other platforms, but on HDMI
 * there's an extra 1 line difference. So we need to add two instead of
 * one to the value.
+*
+* On VLV/CHV DSI the scanline counter would appear to increment
+* approx. 1/3 of a scanline before start of vblank. Unfortunately
+* that means we can't tell whether we're in vblank or not while
+* we're on that particular line. We must still set scanline_offset
+* to 1 so that the vblank timestamps come out correct when we query
+* the scanline counter from within the vblank interrupt handler.
+* However if queried just before the start of vblank we'll get an
+* answer that's slightly in the future.
 */
if (IS_GEN2(dev_priv)) {
const struct drm_display_mode *adjusted_mode = 
>config->base.adjusted_mode;
diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
b/drivers/gpu/drm/i915/intel_sprite.c
index 7031bc733d97..fb0e0d8e893a 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -81,10 +81,13 @@ int intel_usecs_to_scanlines(const struct drm_display_mode 
*adjusted_mode,
  */
 void intel_pipe_update_start(struct intel_crtc *crtc)
 {
+   struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
const struct drm_display_mode *adjusted_mode = 
>config->base.adjusted_mode;
long timeout = msecs_to_jiffies_timeout(1);
int scanline, min, max, vblank_start;
wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(>base);
+   bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || 
IS_CHERRYVIEW(dev_priv)) &&
+   intel_crtc_has_type(crtc->config, INTEL_OUTPUT_DSI);
DEFINE_WAIT(wait);
 
vblank_start = adjusted_mode->crtc_vblank_start;
@@ -136,6 +139,24 @@ void intel_pipe_update_start(struct intel_crtc *crtc)
 
drm_crtc_vblank_put(>base);
 
+   /*
+* On VLV/CHV DSI the scanline counter would appear to
+* increment approx. 1/3 of a scanline before start of vblank.
+* The registers still get latched at start of vblank however.
+* This means we must not write any registers on the first
+* line of vblank (since not the whole line is actually in
+* vblank). And unfortunately we can't use the interrupt to
+* wait here since it will fire too soon. We could use the
+* frame start interrupt instead since it will fire after the
+* critical scanline, but that would require more changes
+* in the interrupt code. So for now we'll just do the nasty
+* thing and poll for the bad scanline to pass us by.
+*
+* FIXME figure out if BXT+ DSI suffers from this as well
+*/
+   while (need_vlv_dsi_wa && scanline == vblank_start)
+   

Re: [Intel-gfx] [PATCH i-g-t] tests: Add kms_plane_blinker

2016-12-15 Thread Ville Syrjälä
On Thu, Dec 15, 2016 at 06:42:08PM +0200, Ville Syrjälä wrote:
> On Thu, Dec 15, 2016 at 04:41:51PM +0100, Maarten Lankhorst wrote:
> > Op 15-12-16 om 16:36 schreef Ville Syrjälä:
> > > On Thu, Dec 15, 2016 at 04:28:52PM +0100, Maarten Lankhorst wrote:
> > >> Op 15-12-16 om 16:23 schreef Ville Syrjälä:
> > >>> On Thu, Dec 15, 2016 at 04:17:45PM +0100, Maarten Lankhorst wrote:
> >  Op 12-12-16 om 21:35 schreef ville.syrj...@linux.intel.com:
> > > From: Ville Syrjälä 
> > >
> > > Add a test to try out all the different plane enable/disable
> > > order permutations.
> > >
> > > Signed-off-by: Ville Syrjälä 
> >  Didn't look through the test, but sounds like
> > 
> >  kms_atomic_transitions.plane-*-transition-* ?
> > 
> >  Although that one tests a few more edge cases like modeset disable and 
> >  nonblocking updates..
> > >>> I don't immediately see where it would try all the permutations, nor can
> > >>> I see any crc_nonblock() stuff so doesn't seem like it could even spot
> > >>> transient errors.
> > >>>
> > >> I haven't done any crc test there yet, but the double loop in 
> > >> run_transition_test handles all combinations of planes.
> > > permutations > combinations
> > >
> > It permutates too, I used it for some basic wm testing before. :)
> 
> Does it? I'm too lazy to reverse engineed it, so I just tried to run it
> but it didn't want to run, so meh.

Needed i915.nuclear_pageflip=1. Didn't even know we had such a knob.

Anywyas, all it tells me is
"Running test on pipe A with resolution 1920x1080 and sprite size 1920x1080 
alpha 1"
and similar lines, and mostly I just see a black screen or a blinking backlight.
So I can't tell what it's actually doing.

-- 
Ville Syrjälä
Intel OTC
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 01/14] drm/i915: Track visible planes in a bitmask

2016-12-15 Thread Ville Syrjälä
On Thu, Dec 15, 2016 at 06:11:24PM +0100, Maarten Lankhorst wrote:
> Op 15-12-16 om 16:02 schreef Ville Syrjälä:
> > On Thu, Dec 15, 2016 at 03:56:03PM +0100, Maarten Lankhorst wrote:
> >> Op 12-12-16 om 21:35 schreef ville.syrj...@linux.intel.com:
> >>> From: Ville Syrjälä 
> >>>
> >>> In a lot of place we wish to know which planes on the crtc are actually
> >>> visible, or how many of them there are. Let's start tracking that in a
> >>> bitmask in the crtc state.
> >>>
> >>> We already track enabled planes (ie. ones with an fb and crtc specified by
> >>> the user) but that's not quite the same thing as enabled planes may
> >>> still end up being invisible due to clipping and whatnot.
> >>>
> >>> Signed-off-by: Ville Syrjälä 
> >>> ---
> >>>  drivers/gpu/drm/i915/intel_atomic_plane.c |  6 +++
> >>>  drivers/gpu/drm/i915/intel_display.c  | 79 
> >>> +--
> >>>  drivers/gpu/drm/i915/intel_drv.h  |  3 ++
> >>>  3 files changed, 64 insertions(+), 24 deletions(-)
> >>>
> >>> diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c 
> >>> b/drivers/gpu/drm/i915/intel_atomic_plane.c
> >>> index dbe9fb41ae53..7ec12edda4d4 100644
> >>> --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
> >>> +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
> >>> @@ -181,6 +181,12 @@ static int intel_plane_atomic_check(struct drm_plane 
> >>> *plane,
> >>>   if (ret)
> >>>   return ret;
> >>>  
> >>> + /* FIXME pre-g4x don't work like this */
> >>> + if (intel_state->base.visible)
> >>> + crtc_state->active_planes |= BIT(intel_plane->id);
> >>> + else
> >>> + crtc_state->active_planes &= ~BIT(intel_plane->id);
> >>> +
> >>>   return intel_plane_atomic_calc_changes(_state->base, state);
> >>>  }
> >>>  
> >>> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> >>> b/drivers/gpu/drm/i915/intel_display.c
> >>> index bc1af87789bc..3f027341b0f3 100644
> >>> --- a/drivers/gpu/drm/i915/intel_display.c
> >>> +++ b/drivers/gpu/drm/i915/intel_display.c
> >>> @@ -2741,6 +2741,29 @@ update_state_fb(struct drm_plane *plane)
> >>>  }
> >>>  
> >>>  static void
> >>> +intel_set_plane_visible(struct intel_crtc_state *crtc_state,
> >>> + struct intel_plane_state *plane_state,
> >>> + bool visible)
> >>> +{
> >>> + struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
> >>> +
> >>> + plane_state->base.visible = visible;
> >>> +
> >>> + /* FIXME pre-g4x don't work like this */
> >>> + if (visible) {
> >>> + crtc_state->base.plane_mask |= 
> >>> BIT(drm_plane_index(>base));
> >>> + crtc_state->active_planes |= BIT(plane->id);
> >>> + } else {
> >>> + crtc_state->base.plane_mask &= 
> >>> ~BIT(drm_plane_index(>base));
> >>> + crtc_state->active_planes &= ~BIT(plane->id);
> >>> + }
> >>> +
> >>> + DRM_DEBUG_KMS("%s active planes 0x%x\n",
> >>> +   crtc_state->base.crtc->name,
> >>> +   crtc_state->active_planes);
> >>> +}
> >>> +
> >>> +static void
> >>>  intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
> >>>struct intel_initial_plane_config *plane_config)
> >>>  {
> >>> @@ -2798,8 +2821,9 @@ intel_find_initial_plane_obj(struct intel_crtc 
> >>> *intel_crtc,
> >>>* simplest solution is to just disable the primary plane now and
> >>>* pretend the BIOS never had it enabled.
> >>>*/
> >>> - to_intel_plane_state(plane_state)->base.visible = false;
> >>> - crtc_state->plane_mask &= ~(1 << drm_plane_index(primary));
> >>> + intel_set_plane_visible(to_intel_crtc_state(crtc_state),
> >>> + to_intel_plane_state(plane_state),
> >>> + false);
> >>>   intel_pre_disable_primary_noatomic(_crtc->base);
> >>>   intel_plane->disable_plane(primary, _crtc->base);
> >>>  
> >>> @@ -2826,7 +2850,11 @@ intel_find_initial_plane_obj(struct intel_crtc 
> >>> *intel_crtc,
> >>>   drm_framebuffer_reference(fb);
> >>>   primary->fb = primary->state->fb = fb;
> >>>   primary->crtc = primary->state->crtc = _crtc->base;
> >>> - intel_crtc->base.state->plane_mask |= (1 << drm_plane_index(primary));
> >>> +
> >>> + intel_set_plane_visible(to_intel_crtc_state(intel_crtc->base.state),
> >>> + to_intel_plane_state(primary->state),
> >>> + true);
> >>> +
> >>>   atomic_or(to_intel_plane(primary)->frontbuffer_bit,
> >>> >frontbuffer_bits);
> >>>  }
> >>> @@ -12440,11 +12468,11 @@ int intel_plane_atomic_calc_changes(struct 
> >>> drm_crtc_state *crtc_state,
> >>>   struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc_state);
> >>>   struct drm_crtc *crtc = crtc_state->crtc;
> >>>   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> >>> - struct drm_plane *plane = plane_state->plane;
> >>> + struct intel_plane *plane = to_intel_plane(plane_state->plane);
> >>>   struct drm_device *dev = crtc->dev;
> >>>   

Re: [Intel-gfx] [PATCH 07/13] drm: Clean up connectors by unreferencing them

2016-12-15 Thread Harry Wentland

On 2016-12-13 06:08 PM, Daniel Vetter wrote:

Only static connectors should be left at this point, and we should be
able to clean them out by simply dropping that last reference still
around from drm_connector_init.

If that leaves anything behind then we have a driver bug.

Doing the final cleanup this way also allows us to use
drm_connector_iter, removing the very last place where we walk
connector_list explicitly in drm core

Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_mode_config.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_mode_config.c 
b/drivers/gpu/drm/drm_mode_config.c
index 747a26df0e90..a942536abd60 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -397,7 +397,8 @@ EXPORT_SYMBOL(drm_mode_config_init);
  */
 void drm_mode_config_cleanup(struct drm_device *dev)
 {
-   struct drm_connector *connector, *ot;
+   struct drm_connector *connector;
+   struct drm_connector_list_iter conn_iter;
struct drm_crtc *crtc, *ct;
struct drm_encoder *encoder, *enct;
struct drm_framebuffer *fb, *fbt;
@@ -410,10 +411,16 @@ void drm_mode_config_cleanup(struct drm_device *dev)
encoder->funcs->destroy(encoder);
}

-   list_for_each_entry_safe(connector, ot,
->mode_config.connector_list, head) {
-   connector->funcs->destroy(connector);
+   drm_connector_list_iter_get(dev, _iter);
+   drm_for_each_connector_iter(connector, _iter) {
+   /* drm_connector_list_iter holds an full reference to the
+* current connector itself, which means it is inherently safe
+* against unreferencing the current connector - but not against
+* deleting it right away. */
+   drm_connector_unreference(connector);
}
+   drm_connector_list_iter_put(_iter);
+   WARN_ON(!list_empty(>mode_config.connector_list));

list_for_each_entry_safe(property, pt, >mode_config.property_list,
 head) {



Reviewed-by: Harry Wentland 

Harry
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 07/14] drm/i915: Compute vlv/chv wms the atomic way

2016-12-15 Thread Ville Syrjälä
On Thu, Dec 15, 2016 at 06:12:12PM +0100, Maarten Lankhorst wrote:
> Op 15-12-16 om 17:09 schreef Ville Syrjälä:
> > On Thu, Dec 15, 2016 at 04:45:49PM +0100, Maarten Lankhorst wrote:
> >> Op 15-12-16 om 16:38 schreef Ville Syrjälä:
> >>> On Thu, Dec 15, 2016 at 04:30:54PM +0100, Maarten Lankhorst wrote:
>  Op 12-12-16 om 21:35 schreef ville.syrj...@linux.intel.com:
> > From: Ville Syrjälä 
> >
> > Start computing the vlv/chv watermarks the atomic way, from the
> > .compute_pipe_wm() hook. We'll recompute the actual watermarks
> > for only planes that are part of the state, the other planes will
> > keep their watermark from the last time it was computed.
> >
> > And the actual watermark programming will happen from the
> > .initial_watermarks() hook. For now we'll just compute the
> > optimal watermarks, and we'll hook up the intermediate
> > watermarks properly later.
> >
> > The DSPARB registers responsible for the FIFO paritioning are
> > double buffered, so they will be programming from
> > intel_begin_crtc_commit().
> >
> > Signed-off-by: Ville Syrjälä 
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h  |   8 +
> >  drivers/gpu/drm/i915/intel_display.c |  21 ++-
> >  drivers/gpu/drm/i915/intel_drv.h |   2 -
> >  drivers/gpu/drm/i915/intel_pm.c  | 327 
> > +++
> >  4 files changed, 238 insertions(+), 120 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h 
> > b/drivers/gpu/drm/i915/i915_drv.h
> > index 20bc04d5e617..f23698f99685 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -493,6 +493,14 @@ struct i915_hotplug {
> > for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) 
> > \
> > for_each_if ((1 << (domain)) & (mask))
> >  
> > +#define for_each_intel_plane_in_state(__state, plane, plane_state, 
> > __i) \
> > +   for ((__i) = 0; \
> > +(__i) < (__state)->base.dev->mode_config.num_total_plane 
> > && \
> > +((plane) = 
> > to_intel_plane((__state)->base.planes[__i].ptr), \
> > + (plane_state) = 
> > to_intel_plane_state((__state)->base.planes[__i].state), 1); \
> > +(__i)++) \
> > +   for_each_if (plane_state)
> > +
> >  struct drm_i915_private;
> >  struct i915_mm_struct;
> >  struct i915_mmu_object;
> > diff --git a/drivers/gpu/drm/i915/intel_display.c 
> > b/drivers/gpu/drm/i915/intel_display.c
> > index 3f027341b0f3..8d80873b6643 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -6736,6 +6736,8 @@ static void 
> > valleyview_modeset_commit_cdclk(struct drm_atomic_state *old_state)
> >  static void valleyview_crtc_enable(struct intel_crtc_state 
> > *pipe_config,
> >struct drm_atomic_state *old_state)
> >  {
> > +   struct intel_atomic_state *old_intel_state =
> > +   to_intel_atomic_state(old_state);
> > struct drm_crtc *crtc = pipe_config->base.crtc;
> > struct drm_device *dev = crtc->dev;
> > struct drm_i915_private *dev_priv = to_i915(dev);
> > @@ -6780,7 +6782,8 @@ static void valleyview_crtc_enable(struct 
> > intel_crtc_state *pipe_config,
> >  
> > intel_color_load_luts(_config->base);
> >  
> > -   intel_update_watermarks(intel_crtc);
> > +   dev_priv->display.initial_watermarks(old_intel_state,
> > +pipe_config);
> > intel_enable_pipe(intel_crtc);
> >  
> > assert_vblank_disabled(crtc);
> > @@ -6897,6 +6900,9 @@ static void i9xx_crtc_disable(struct 
> > intel_crtc_state *old_crtc_state,
> >  
> > if (!IS_GEN2(dev_priv))
> > intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, 
> > false);
> > +
> > +   if (!dev_priv->display.initial_watermarks)
> > +   intel_update_watermarks(intel_crtc);
> >  }
> >  
> >  static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
> > @@ -12980,10 +12986,13 @@ static bool 
> > check_digital_port_conflicts(struct drm_atomic_state *state)
> >  static void
> >  clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
> >  {
> > +   struct drm_i915_private *dev_priv =
> > +   to_i915(crtc_state->base.crtc->dev);
> > struct drm_crtc_state tmp_state;
> > struct intel_crtc_scaler_state scaler_state;
> > struct intel_dpll_hw_state dpll_hw_state;
> > struct intel_shared_dpll *shared_dpll;

[Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915: use udelay for very small delays

2016-12-15 Thread Patchwork
== Series Details ==

Series: drm/i915: use udelay for very small delays
URL   : https://patchwork.freedesktop.org/series/16852/
State : success

== Summary ==

Series 16852v1 drm/i915: use udelay for very small delays
https://patchwork.freedesktop.org/api/1.0/series/16852/revisions/1/mbox/

Test kms_pipe_crc_basic:
Subgroup bad-nb-words-1:
dmesg-warn -> PASS   (fi-snb-2520m)

fi-bdw-5557u total:247  pass:233  dwarn:0   dfail:0   fail:0   skip:14 
fi-bsw-n3050 total:247  pass:208  dwarn:0   dfail:0   fail:0   skip:39 
fi-bxt-j4205 total:247  pass:222  dwarn:0   dfail:0   fail:0   skip:25 
fi-bxt-t5700 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
fi-byt-j1900 total:247  pass:220  dwarn:0   dfail:0   fail:0   skip:27 
fi-byt-n2820 total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31 
fi-hsw-4770  total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19 
fi-hsw-4770r total:247  pass:228  dwarn:0   dfail:0   fail:0   skip:19 
fi-ilk-650   total:247  pass:195  dwarn:0   dfail:0   fail:0   skip:52 
fi-ivb-3520m total:247  pass:226  dwarn:0   dfail:0   fail:0   skip:21 
fi-kbl-7500u total:247  pass:226  dwarn:0   dfail:0   fail:0   skip:21 
fi-skl-6260u total:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13 
fi-skl-6700hqtotal:247  pass:227  dwarn:0   dfail:0   fail:0   skip:20 
fi-skl-6700k total:247  pass:224  dwarn:3   dfail:0   fail:0   skip:20 
fi-skl-6770hqtotal:247  pass:234  dwarn:0   dfail:0   fail:0   skip:13 
fi-snb-2520m total:247  pass:216  dwarn:0   dfail:0   fail:0   skip:31 
fi-snb-2600  total:247  pass:215  dwarn:0   dfail:0   fail:0   skip:32 

a16fc233af5c80d1ed23178c94b7fbb77e48ffe0 drm-tip: 2016y-12m-15d-15h-21m-31s UTC 
integration manifest
0f212d4 drm/i915: use udelay for very small delays

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_3297/
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 07/14] drm/i915: Compute vlv/chv wms the atomic way

2016-12-15 Thread Maarten Lankhorst
Op 15-12-16 om 17:09 schreef Ville Syrjälä:
> On Thu, Dec 15, 2016 at 04:45:49PM +0100, Maarten Lankhorst wrote:
>> Op 15-12-16 om 16:38 schreef Ville Syrjälä:
>>> On Thu, Dec 15, 2016 at 04:30:54PM +0100, Maarten Lankhorst wrote:
 Op 12-12-16 om 21:35 schreef ville.syrj...@linux.intel.com:
> From: Ville Syrjälä 
>
> Start computing the vlv/chv watermarks the atomic way, from the
> .compute_pipe_wm() hook. We'll recompute the actual watermarks
> for only planes that are part of the state, the other planes will
> keep their watermark from the last time it was computed.
>
> And the actual watermark programming will happen from the
> .initial_watermarks() hook. For now we'll just compute the
> optimal watermarks, and we'll hook up the intermediate
> watermarks properly later.
>
> The DSPARB registers responsible for the FIFO paritioning are
> double buffered, so they will be programming from
> intel_begin_crtc_commit().
>
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/i915_drv.h  |   8 +
>  drivers/gpu/drm/i915/intel_display.c |  21 ++-
>  drivers/gpu/drm/i915/intel_drv.h |   2 -
>  drivers/gpu/drm/i915/intel_pm.c  | 327 
> +++
>  4 files changed, 238 insertions(+), 120 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h 
> b/drivers/gpu/drm/i915/i915_drv.h
> index 20bc04d5e617..f23698f99685 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -493,6 +493,14 @@ struct i915_hotplug {
>   for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) \
>   for_each_if ((1 << (domain)) & (mask))
>  
> +#define for_each_intel_plane_in_state(__state, plane, plane_state, __i) \
> + for ((__i) = 0; \
> +  (__i) < (__state)->base.dev->mode_config.num_total_plane && \
> +  ((plane) = 
> to_intel_plane((__state)->base.planes[__i].ptr), \
> +   (plane_state) = 
> to_intel_plane_state((__state)->base.planes[__i].state), 1); \
> +  (__i)++) \
> + for_each_if (plane_state)
> +
>  struct drm_i915_private;
>  struct i915_mm_struct;
>  struct i915_mmu_object;
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index 3f027341b0f3..8d80873b6643 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -6736,6 +6736,8 @@ static void valleyview_modeset_commit_cdclk(struct 
> drm_atomic_state *old_state)
>  static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config,
>  struct drm_atomic_state *old_state)
>  {
> + struct intel_atomic_state *old_intel_state =
> + to_intel_atomic_state(old_state);
>   struct drm_crtc *crtc = pipe_config->base.crtc;
>   struct drm_device *dev = crtc->dev;
>   struct drm_i915_private *dev_priv = to_i915(dev);
> @@ -6780,7 +6782,8 @@ static void valleyview_crtc_enable(struct 
> intel_crtc_state *pipe_config,
>  
>   intel_color_load_luts(_config->base);
>  
> - intel_update_watermarks(intel_crtc);
> + dev_priv->display.initial_watermarks(old_intel_state,
> +  pipe_config);
>   intel_enable_pipe(intel_crtc);
>  
>   assert_vblank_disabled(crtc);
> @@ -6897,6 +6900,9 @@ static void i9xx_crtc_disable(struct 
> intel_crtc_state *old_crtc_state,
>  
>   if (!IS_GEN2(dev_priv))
>   intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
> +
> + if (!dev_priv->display.initial_watermarks)
> + intel_update_watermarks(intel_crtc);
>  }
>  
>  static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
> @@ -12980,10 +12986,13 @@ static bool check_digital_port_conflicts(struct 
> drm_atomic_state *state)
>  static void
>  clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
>  {
> + struct drm_i915_private *dev_priv =
> + to_i915(crtc_state->base.crtc->dev);
>   struct drm_crtc_state tmp_state;
>   struct intel_crtc_scaler_state scaler_state;
>   struct intel_dpll_hw_state dpll_hw_state;
>   struct intel_shared_dpll *shared_dpll;
> + struct intel_crtc_wm_state wm_state;
>   bool force_thru;
>  
>   /* FIXME: before the switch to atomic started, a new pipe_config was
> @@ -12996,6 +13005,8 @@ clear_intel_crtc_state(struct intel_crtc_state 
> *crtc_state)
>   shared_dpll = crtc_state->shared_dpll;
>   dpll_hw_state = crtc_state->dpll_hw_state;
>   force_thru = crtc_state->pch_pfit.force_thru;
> + if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> + wm_state 

Re: [Intel-gfx] [PATCH 01/14] drm/i915: Track visible planes in a bitmask

2016-12-15 Thread Maarten Lankhorst
Op 15-12-16 om 16:02 schreef Ville Syrjälä:
> On Thu, Dec 15, 2016 at 03:56:03PM +0100, Maarten Lankhorst wrote:
>> Op 12-12-16 om 21:35 schreef ville.syrj...@linux.intel.com:
>>> From: Ville Syrjälä 
>>>
>>> In a lot of place we wish to know which planes on the crtc are actually
>>> visible, or how many of them there are. Let's start tracking that in a
>>> bitmask in the crtc state.
>>>
>>> We already track enabled planes (ie. ones with an fb and crtc specified by
>>> the user) but that's not quite the same thing as enabled planes may
>>> still end up being invisible due to clipping and whatnot.
>>>
>>> Signed-off-by: Ville Syrjälä 
>>> ---
>>>  drivers/gpu/drm/i915/intel_atomic_plane.c |  6 +++
>>>  drivers/gpu/drm/i915/intel_display.c  | 79 
>>> +--
>>>  drivers/gpu/drm/i915/intel_drv.h  |  3 ++
>>>  3 files changed, 64 insertions(+), 24 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c 
>>> b/drivers/gpu/drm/i915/intel_atomic_plane.c
>>> index dbe9fb41ae53..7ec12edda4d4 100644
>>> --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
>>> +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
>>> @@ -181,6 +181,12 @@ static int intel_plane_atomic_check(struct drm_plane 
>>> *plane,
>>> if (ret)
>>> return ret;
>>>  
>>> +   /* FIXME pre-g4x don't work like this */
>>> +   if (intel_state->base.visible)
>>> +   crtc_state->active_planes |= BIT(intel_plane->id);
>>> +   else
>>> +   crtc_state->active_planes &= ~BIT(intel_plane->id);
>>> +
>>> return intel_plane_atomic_calc_changes(_state->base, state);
>>>  }
>>>  
>>> diff --git a/drivers/gpu/drm/i915/intel_display.c 
>>> b/drivers/gpu/drm/i915/intel_display.c
>>> index bc1af87789bc..3f027341b0f3 100644
>>> --- a/drivers/gpu/drm/i915/intel_display.c
>>> +++ b/drivers/gpu/drm/i915/intel_display.c
>>> @@ -2741,6 +2741,29 @@ update_state_fb(struct drm_plane *plane)
>>>  }
>>>  
>>>  static void
>>> +intel_set_plane_visible(struct intel_crtc_state *crtc_state,
>>> +   struct intel_plane_state *plane_state,
>>> +   bool visible)
>>> +{
>>> +   struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
>>> +
>>> +   plane_state->base.visible = visible;
>>> +
>>> +   /* FIXME pre-g4x don't work like this */
>>> +   if (visible) {
>>> +   crtc_state->base.plane_mask |= 
>>> BIT(drm_plane_index(>base));
>>> +   crtc_state->active_planes |= BIT(plane->id);
>>> +   } else {
>>> +   crtc_state->base.plane_mask &= 
>>> ~BIT(drm_plane_index(>base));
>>> +   crtc_state->active_planes &= ~BIT(plane->id);
>>> +   }
>>> +
>>> +   DRM_DEBUG_KMS("%s active planes 0x%x\n",
>>> + crtc_state->base.crtc->name,
>>> + crtc_state->active_planes);
>>> +}
>>> +
>>> +static void
>>>  intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
>>>  struct intel_initial_plane_config *plane_config)
>>>  {
>>> @@ -2798,8 +2821,9 @@ intel_find_initial_plane_obj(struct intel_crtc 
>>> *intel_crtc,
>>>  * simplest solution is to just disable the primary plane now and
>>>  * pretend the BIOS never had it enabled.
>>>  */
>>> -   to_intel_plane_state(plane_state)->base.visible = false;
>>> -   crtc_state->plane_mask &= ~(1 << drm_plane_index(primary));
>>> +   intel_set_plane_visible(to_intel_crtc_state(crtc_state),
>>> +   to_intel_plane_state(plane_state),
>>> +   false);
>>> intel_pre_disable_primary_noatomic(_crtc->base);
>>> intel_plane->disable_plane(primary, _crtc->base);
>>>  
>>> @@ -2826,7 +2850,11 @@ intel_find_initial_plane_obj(struct intel_crtc 
>>> *intel_crtc,
>>> drm_framebuffer_reference(fb);
>>> primary->fb = primary->state->fb = fb;
>>> primary->crtc = primary->state->crtc = _crtc->base;
>>> -   intel_crtc->base.state->plane_mask |= (1 << drm_plane_index(primary));
>>> +
>>> +   intel_set_plane_visible(to_intel_crtc_state(intel_crtc->base.state),
>>> +   to_intel_plane_state(primary->state),
>>> +   true);
>>> +
>>> atomic_or(to_intel_plane(primary)->frontbuffer_bit,
>>>   >frontbuffer_bits);
>>>  }
>>> @@ -12440,11 +12468,11 @@ int intel_plane_atomic_calc_changes(struct 
>>> drm_crtc_state *crtc_state,
>>> struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc_state);
>>> struct drm_crtc *crtc = crtc_state->crtc;
>>> struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>>> -   struct drm_plane *plane = plane_state->plane;
>>> +   struct intel_plane *plane = to_intel_plane(plane_state->plane);
>>> struct drm_device *dev = crtc->dev;
>>> struct drm_i915_private *dev_priv = to_i915(dev);
>>> struct intel_plane_state *old_plane_state =
>>> -   to_intel_plane_state(plane->state);
>>> +   

Re: [Intel-gfx] [PATCH 14/14] drm/i915: Kill level 0 wm hack for VLV/CHV

2016-12-15 Thread Maarten Lankhorst
Op 12-12-16 om 21:35 schreef ville.syrj...@linux.intel.com:
> From: Ville Syrjälä 
>
> We now compute the watermarks correctly, so just return an error if we
> can't support the configuration.
>
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 4 
>  1 file changed, 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 75a5bde43723..f3aed64e7086 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -1163,10 +1163,6 @@ static bool vlv_plane_wm_compute(struct 
> intel_crtc_state *crtc_state,
>   int wm = vlv_compute_wm_level(crtc_state, plane_state, level);
>   int max_wm = plane_id == PLANE_CURSOR ? 63 : 511;
>  
> - /* FIXME just bail */
> - if (WARN_ON(level == 0 && wm > max_wm))
> - wm = max_wm;
> -
>   if (wm > max_wm)
>   break;
>  

Good riddance.

Reviewed-by: Maarten Lankhorst 

Same for 3, 4, 5 and 6. 2 too if you remove intel_plane_wm_parameters, can do 
it in the same patch or separately.

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v2] drm/i915: Optimise VMA lookup slightly

2016-12-15 Thread Chris Wilson
On Thu, Dec 15, 2016 at 04:49:49PM +, Tvrtko Ursulin wrote:
> 
> On 13/12/2016 14:47, Chris Wilson wrote:
> >On Tue, Dec 13, 2016 at 02:37:27PM +, Tvrtko Ursulin wrote:
> >>From: Tvrtko Ursulin 
> >>
> >>Cast VM pointers before substraction to save the compiler
> >>doing a smart one which includes multiplication.
> >>
> >>v2: Only keep the first optimisation and prettify it. (Chris Wilson)
> >>
> >>Signed-off-by: Tvrtko Ursulin 
> >>Cc: Chris Wilson 
> >
> >Step 1, ok.
> >Reviewed-by: Chris Wilson 
> >
> >(I wasn't against the others, just curious as to what gcc was doing for
> >#2 and #3 I'd like just to pursue a different path altogether :)
> 
> Thanks.
> 
> Yes I know. Longer VMA lists is not something I've tested yet. I've
> just noticed that even where lookups are predominantly on short
> lists it can still be up to 1% of CPU time spent in the lookup. It
> averages around 0.7% AFAIR.
> 
> More precisely in that test (which is simply running a vsync limited
> neverball intro screen :)), 65% of all lookups are on single VMA
> object! 29% on objects with two VMAs and 29% on on objects with
> three VMAs. That's it, no longer lists at all.

Also note that I've been trying to teach mesa not to be so dumb as well.
We still do get benefits from improving the execbuf vma/reloc paths, but
that pales in comparison to the improvements we can make in mesa.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v7 8/8] drm/i915/gen9: WM memory bandwidth related workaround

2016-12-15 Thread Paulo Zanoni
Em Qui, 2016-12-01 às 21:19 +0530, Mahesh Kumar escreveu:
> This patch implemnets Workariunds related to display arbitrated
> memory
> bandwidth. These WA are applicabe for all gen-9 based platforms.

3 typos above.

The WA is already implemented. What the patch does is that it opts-out
of the WA in case we conclude it's safe. Please say this in the commit
message.

> 
> Changes since v1:
>  - Rebase on top of Paulo's patch series
> Changes since v2:
>  - Address review comments
>  - Rebase/rework as per other patch changes in series
> Changes since v3:
>  - Rework based on Maarten's comments
> 
> Signed-off-by: Mahesh Kumar 
> ---
>  drivers/gpu/drm/i915/i915_drv.h  |  11 +++
>  drivers/gpu/drm/i915/intel_display.c |  24 ++
>  drivers/gpu/drm/i915/intel_pm.c  | 155
> +--
>  3 files changed, 181 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> index 69213a4..3126259 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1216,6 +1216,13 @@ enum intel_sbi_destination {
>   SBI_MPHY,
>  };
>  
> +/* SKL+ Watermark arbitrated display bandwidth Workarounds */
> +enum watermark_memory_wa {
> + WATERMARK_WA_NONE,
> + WATERMARK_WA_X_TILED,
> + WATERMARK_WA_Y_TILED,
> +};
> +
>  #define QUIRK_PIPEA_FORCE (1<<0)
>  #define QUIRK_LVDS_SSC_DISABLE (1<<1)
>  #define QUIRK_INVERT_BRIGHTNESS (1<<2)
> @@ -1788,6 +1795,10 @@ struct skl_ddb_allocation {
>  
>  struct skl_wm_values {
>   unsigned dirty_pipes;
> + /* any WaterMark memory workaround Required */

CapitaliZation is weird Here. Besides, no need for the comment.


> + enum watermark_memory_wa mem_wa;
> + uint32_t pipe_bw_kbps[I915_MAX_PIPES];
> + bool pipe_ytiled[I915_MAX_PIPES];
>   struct skl_ddb_allocation ddb;
>  };
>  
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index 5d11002..f8da488 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -14574,6 +14574,28 @@ static void intel_atomic_track_fbs(struct
> drm_atomic_state *state)
>     to_intel_plane(plane)-
> >frontbuffer_bit);
>  }
>  
> +static void
> +intel_update_wm_bw_wa(struct drm_atomic_state *state)
> +{
> + struct intel_atomic_state *intel_state =
> to_intel_atomic_state(state);
> + struct drm_i915_private *dev_priv = to_i915(state->dev);
> + const struct drm_crtc *crtc;
> + const struct drm_crtc_state *cstate;
> + struct skl_wm_values *results = _state->wm_results;
> + struct skl_wm_values *hw_vals = _priv->wm.skl_hw;
> + int i;
> +
> + if (!IS_GEN9(dev_priv))
> + return;
> +
> + for_each_crtc_in_state(state, crtc, cstate, i) {
> + hw_vals->pipe_bw_kbps[i] = results->pipe_bw_kbps[i];
> + hw_vals->pipe_ytiled[i] = results->pipe_ytiled[i];
> + }
> +
> + hw_vals->mem_wa = results->mem_wa;
> +}

I think we can just patch skl_copy_wm_for_pipe() to also copy the
fields we need instead of adding this function. Whouldn't that be much
simpler? Anyway, this one looks correct, so no need to change if you
don't want.


> +
>  /**
>   * intel_atomic_commit - commit validated state object
>   * @dev: DRM device
> @@ -14614,6 +14636,8 @@ static int intel_atomic_commit(struct
> drm_device *dev,
>   intel_shared_dpll_commit(state);
>   intel_atomic_track_fbs(state);
>  
> + intel_update_wm_bw_wa(state);
> +
>   if (intel_state->modeset) {
>   memcpy(dev_priv->min_pixclk, intel_state-
> >min_pixclk,
>      sizeof(intel_state->min_pixclk));
> diff --git a/drivers/gpu/drm/i915/intel_pm.c
> b/drivers/gpu/drm/i915/intel_pm.c
> index cc8fc84..fda6e1e 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2878,11 +2878,7 @@ bool ilk_disable_lp_wm(struct drm_device *dev)
>  
>  #define SKL_SAGV_BLOCK_TIME  30 /* µs */
>  
> -/*
> - * FIXME: We still don't have the proper code detect if we need to
> apply the WA,
> - * so assume we'll always need it in order to avoid underruns.
> - */
> -static bool skl_needs_memory_bw_wa(struct intel_atomic_state *state)
> +static bool intel_needs_memory_bw_wa(struct intel_atomic_state
> *state)

Why are we renaming this function?

Also, in my last review I suggested that we kill this function. I don't
think it makes sense to have this function anymore.

Besides, function intel_can_enable_sagv() needs to look at the value we
assigned to enum watermark_memory_wa, not get a true/false based on
platform version.


>  {
>   struct drm_i915_private *dev_priv = to_i915(state-
> >base.dev);
>  
> @@ -3056,7 +3052,7 @@ bool intel_can_enable_sagv(struct
> drm_atomic_state *state)
>  
>   latency = dev_priv->wm.skl_latency[level];
>  
> - if (skl_needs_memory_bw_wa(intel_state) 

  1   2   3   >